2024-04-11 10:18:52 +02:00
|
|
|
|
2024-04-11 14:14:08 +02:00
|
|
|
## Organization
|
|
|
|
- [ init.lua](./init.lua) - module entrypoint. The other files are included from here
|
|
|
|
and several constants are defined here
|
|
|
|
|
|
|
|
- [carts.lua](./carts/lua) - This file contains code related to cart entities, cart
|
|
|
|
type registration, creation, estruction and updating. The global step function
|
|
|
|
responsible for updating attached carts is in this file. The various carts are
|
|
|
|
referenced from this file but actually reside in the subdirectory [carts/](./carts/).
|
|
|
|
|
|
|
|
- [functions.lua](./functions.lua) - This file contains various minecart and rail
|
|
|
|
utility functions used by the rest of the code.
|
|
|
|
|
|
|
|
- [movement.lua](./movement.lua) - This file contains the code related to cart
|
|
|
|
movement physics.
|
|
|
|
|
|
|
|
- [rails.lua](./rails.lua) - This file contains code related to rail registation,
|
|
|
|
placement, connection rules and cart direction selection. This contains the rail
|
|
|
|
behaviors and the LBM code for updating legacy rail nodes to the new versions
|
2024-04-11 14:33:22 +02:00
|
|
|
that don't use the raillike draw type.
|
2024-04-11 14:14:08 +02:00
|
|
|
|
|
|
|
- [storage.lua](./storage.lua) - This file contains the code than manages minecart
|
|
|
|
state data to allow processing minecarts while entities are unloaded.
|
|
|
|
|
|
|
|
- [train.lua](./train.lua) - This file contains code related to multi-car trains.
|
|
|
|
|
2024-04-11 14:33:22 +02:00
|
|
|
## Rail Nodes
|
|
|
|
|
|
|
|
Previous versions of mcl\_minecarts used one node type for each rail type (standard,
|
|
|
|
powered, detector and activator) using the raillike draw type that minetest provides.
|
|
|
|
This version does not use the raillike draw type and instead uses a 1/16th of a block
|
|
|
|
high nodebox and uses an additional node definition for each variant. The variants
|
|
|
|
present are:
|
|
|
|
|
|
|
|
- straight
|
|
|
|
- sloped
|
|
|
|
- corner
|
|
|
|
- tee
|
|
|
|
- cross
|
|
|
|
|
|
|
|
Of the rail types provided by this module, standard has all of these variants. The
|
|
|
|
remaining types only have straight and sloped variants.
|
|
|
|
|
|
|
|
Unlike the old rail type, this version will only update connections when placed, and
|
|
|
|
will only place a variant that already has connections into the space the rail is
|
|
|
|
being placed. Here is how to create the various varients:
|
|
|
|
|
|
|
|
- Straight rail is placed when with zero or one adjacent rail nodes. If no rails
|
|
|
|
are adjacent, the rail is placed in line with the direction the player is facing.
|
|
|
|
If there is exactly one adjacent rail present, the straight rail will always rotate
|
|
|
|
to connect to it.
|
|
|
|
|
|
|
|
- Sloped rail is placed when there are two rails in a straight line, with one being
|
|
|
|
one block higher. When rail is placed adjacent to a straight rail one block lower
|
|
|
|
and the rail is facing the block the rail is being placed on, the lower rail will
|
|
|
|
convert into a slope.
|
|
|
|
|
|
|
|
- A corner rail is placed when there are exactly two adjacent rails that are not in
|
|
|
|
a line and lead into the space the rail is being placed. The corner will be rotated
|
|
|
|
to connect these two rails.
|
|
|
|
|
|
|
|
- A tee rail is placed where there are exactly three rails adjact and those existing
|
|
|
|
rails lead into the the space the new rail is being placed.
|
|
|
|
|
|
|
|
- A rail cross is placed when there is rail in all four adjacent blocks and they all
|
|
|
|
have a path into the space the new rail is being placed.
|
|
|
|
|
|
|
|
The tee variant will interact with redstone and mesecons to switch the curved section.
|
|
|
|
|
2024-04-11 10:18:52 +02:00
|
|
|
## 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
|
2024-04-11 10:33:36 +02:00
|
|
|
and indexed by a hex-encoded 128-bit universally-unique identifier (uuid). Minecart
|
|
|
|
entities store this uuid and a sequence identifier. 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 [Advanced 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.
|
2024-04-11 10:18:52 +02:00
|
|
|
|
|
|
|
Processing for minecart movement is as follows:
|
2024-04-11 10:33:36 +02:00
|
|
|
1. In a globalstep handler in [carts.lua](./carts.lua), determine which carts are
|
|
|
|
moving.
|
2024-04-11 10:18:52 +02:00
|
|
|
2. Call `do_movement` in [movement.lua](./movement.lua) to update
|
2024-04-11 10:33:36 +02:00
|
|
|
each cart's location and handle interactions with the environment.
|
2024-04-11 10:18:52 +02:00
|
|
|
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
|
2024-04-11 10:33:36 +02:00
|
|
|
lag. Each step is processed with `do_movement_step`
|
2024-04-11 10:18:52 +02:00
|
|
|
2. Each step uses physically accurate, timestep-independent physics
|
2024-04-11 10:33:36 +02:00
|
|
|
to move the cart. Calculating the acceleration to apply to a cart
|
|
|
|
is broken out into its own function (`calculate_acceperation`).
|
2024-04-11 10:18:52 +02:00
|
|
|
3. As the cart enters and leaves blocks, handlers in nearby blocks are called
|
2024-04-11 10:33:36 +02:00
|
|
|
to allow the cart to efficiently interact with the environment. Handled by
|
|
|
|
the functions `handle_cart_enter` and `handle_cart_leave`
|
|
|
|
4. The cart checks for nearby carts and collides elastically with these. The
|
|
|
|
calculations for these collisions are in the function `handle_cart_collision`
|
|
|
|
5. If the cart enters a new block, determine the new direction the cart will
|
2024-04-11 11:17:06 +02:00
|
|
|
move with `mcl_minecarts:get_rail_direction` in [functions.lua](./functions.lua).
|
2024-04-11 10:33:36 +02:00
|
|
|
The rail nodes provide a hook `_mcl_minecarts.get_next_direction` that
|
|
|
|
provides this information based on the previous movement direction.
|
2024-04-11 10:18:52 +02:00
|
|
|
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.
|
2024-04-11 10:33:36 +02:00
|
|
|
|