More minor changes to API.md, start overall implementation documentation

This commit is contained in:
teknomunk 2024-04-11 08:18:52 +00:00
parent e5f4650114
commit 99dec4217c
3 changed files with 48 additions and 3 deletions

View file

@ -25,7 +25,7 @@ second. Defined as 10 blocks/second.
- `mcl_minecarts.CART_BLOCKS_SIZE` - `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` - `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 - `ignore_neightbor_connections` - if true, don't check that a cart could leave
the neighboring node from this direction. 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)` `mcl_minecarts.register_rail(itemstring, node_definition)`
Registers a rail with a few sensible defaults and if a craft recipe was specified, Registers a rail with a few sensible defaults and if a craft recipe was specified,

View file

@ -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.

View file

@ -182,7 +182,6 @@ function DEFAULT_CART_DEF:on_step(dtime)
self._staticdata = staticdata self._staticdata = staticdata
end end
-- Update entity position -- Update entity position
local pos = mod.get_cart_position(staticdata) local pos = mod.get_cart_position(staticdata)
if pos then self.object:move_to(pos) end 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 -- TODO: change how often cart positions are updated based on velocity
for uuid,staticdata in mod.carts() do for uuid,staticdata in mod.carts() do
local pos = mod.get_cart_position(staticdata) 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.. print("cart# "..uuid..
",velocity="..tostring(staticdata.velocity).. ",velocity="..tostring(staticdata.velocity)..
",pos="..tostring(pos).. ",pos="..tostring(pos)..