You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is implemented in the fresh MIT-licensed Go server under the replacement program. Its gameplay and content-design decisions remain authoritative. C, CPython, classic packet, file-path, and enum details in the preserved specification are historical evidence only; do not copy, translate, or structurally port GPL implementation code.
Replacement implementation contract
Preserve discrete linked-map altitude, capability/state separation, vertical collision, and cross-depth deferrals. Use stable map/surface identities and bounded generated request/state contracts.
The server remains authoritative, consumes versioned compiled content, and exposes bounded generated Game Protocol 1 messages. Pure rules may use a specifically approved typed CEL environment. Starlark is not part of this issue unless the separate residual-scripting decision explicitly approves it.
Required verification
Preserve every observable rule, balance decision, disclosure boundary, and anti-exploit invariant from the specification below.
Add deterministic Go unit/property tests and wrapper-managed scenario coverage at the appropriate integration boundary.
Add bounded malformed-input and persistence-failure cases where this feature accepts content, network, or stored data.
Add Go/Rust protocol conformance fixtures for every new cross-process field; the client must not reconstruct authoritative rules from prose.
Demonstrate that implementation and tests contain no copied GPL source/test material and execute no runtime Python.
Preserved product/design specification and historical implementation notes
Summary
Add server-authoritative player flight by treating the existing physical TILED_UP/TILED_DOWN map stack as discrete altitude bands. A player who
ascends moves to the linked map at the same world coordinate; ordinary players
remain on their current physical map and can see the flyer through the
already-shipped multi-level map stream whenever LOS and vertical occlusion
allow it.
This should be implemented as a focused first slice: take off, ascend, descend,
land, render, select, save/reconnect, and fall safely when flight is lost.
Cross-depth attacks and fully simulated 3D projectiles should be designed
separately rather than accidentally inheriting inconsistent 2D behavior.
Why this fits the current codebase
Most of the expensive visibility and rendering foundation already exists:
server/src/include/global.h defines TILED_UP and TILED_DOWN, while map
filename coordinates and mapstruct.coords[2] already identify physical
levels.
server/src/socket/request.c:draw_client_map2() resolves and serializes each
visible linked map as a separate, length-delimited CLIENT_CMD_MAP depth.
It applies base-map gameplay LOS, vertical floor/opaque occlusion, building
cutaways, and independent per-depth delta caches.
client/src/gui/widgets/map.c:map_draw_map() projects all active depths with
a 46-pixel level lift and paints them in one cross-level isometric order.
A connected TILED_UP/TILED_DOWN player transition already sends a signed
depth offset. copy_lastmap() and map_level_scroll() shift the server and
client depth caches instead of forcing a full map refresh.
map_redraw() already locates observers across linked levels using rv_vector.distance_z, so an actor moving on an upper map invalidates the
correct depth in a lower player's cache.
There is also an existing but narrower flight concept:
FLAG_FLYING lets an object traverse water/fire/cloud terrain in server/src/server/map.c:blocked() but does not bypass walls or closed doors.
Flying objects use FLY_ON/FLY_OFF instead of WALK_ON/WALK_OFF, do not
press normal floor mechanisms, cannot pick up/apply ordinary ground objects,
and receive the existing combat altitude modifier.
object_insert_map(..., INS_FALL_THROUGH) stops falling when it encounters a
floor or when the object has FLAG_FLYING.
Those pieces mean an actor placed on a linked upper map is already visible to a
ground observer when authorized. The missing feature is a coherent player
state and movement contract that puts the actor there.
Current gaps
Movement is two-dimensional. SERVER_CMD_MOVE accepts only directions
0-8, and move_ob()/object_move_to() only change X/Y or cross horizontal
map edges.
FLAG_FLYING conflates an acquired capability with the active airborne
state. Equipment recalculation directly sets/clears it, so there is no clean
takeoff/landing toggle.
There is no authoritative vertical collision operation. Ascending must not
tunnel through an upper floor/opaque ceiling, and descending must not pass
through the floor of the current level.
Losing flight does not immediately settle an actor. The existing fall-through
path runs on a later insertion/move and should not leave a player suspended
after an effect expires or equipment changes.
Target selection is depth-blind. The client scans only the depth-zero MapCell cache, and CMD_TARGET_MAPXY sends only X, Y, and object count;
the server then searches only the player's physical map.
Combat is mostly 2D. Melee correctly requires the same physical map, while
projectile movement and much spell logic have no intentional cross-depth
trajectory policy.
Existing maps need an explicit way to forbid takeoff or cap ascent so flight
cannot silently bypass indoor, quest, or private-area boundaries.
Proposed model
1. Keep physical maps authoritative for altitude
Do not add a second free-form Z coordinate to players. A player occupies
exactly one authoritative mapstruct; its linked depth is the altitude band.
Ascending or descending one band transfers the player at the same X/Y through
the reciprocal TILED_UP/TILED_DOWN link.
MAP2_MAX_DEPTH remains a render/serialization window, not a promise that the
world has that many flyable levels. The initial implementation must use only
authored/explicitly linked maps and must not synthesize an unbounded stack of
empty air maps.
This naturally gives each observer a relative view:
the flyer's physical map is depth zero for that client;
the ground is a negative depth for the flyer; and
the flyer is a positive depth for a player below.
The existing connected-map update and depth-cache shift should be reused for
vertical movement.
2. Separate capability from state
Introduce a distinct flight capability (for example FLAG_CAN_FLY or a
derived capability query) and retain FLAG_FLYING as the active airborne
state used by terrain, triggers, pickup/apply, and combat rules.
For players:
equipment, spells, skills, or species grant can fly;
takeoff sets flying without changing the current physical map;
losing the last flight capability immediately invokes the landing/fall
resolver and then clears the active state; and
reconnect/load validates the saved physical level against the restored
capability and settles the player if necessary.
Existing flying monsters, spell effects, and projectiles should retain their
current behavior in the first slice. Do not make every FLAG_FLYING object
start changing physical levels implicitly.
3. Add two explicit player actions
Add client actions and default-unbound keybind commands for:
Ascend / Take off: if grounded and capable, enter the airborne state on
the current level; if already airborne, attempt to cross one TILED_UP link.
Descend / Land: if a supporting floor exists on the current level, land
there; otherwise attempt to cross one TILED_DOWN link.
Use a dedicated, strictly framed client-to-server action such as SERVER_CMD_MOVE_VERTICAL with a signed one-step direction. Handle action
cost, paralysis/freeze checks, movement/path cancellation, animation updates,
and rate limiting in the same authoritative layer as ordinary movement. A
text command may be useful for debugging, but should not be the gameplay wire
contract.
Expose can fly and currently flying in player state updates so the client
can disable actions and display an unambiguous status indicator. Horizontal
click-to-move and run paths remain on the current physical map in this slice;
they must never auto-ascend.
4. Make vertical collision directional and shared
Move the reusable vertical-boundary predicate out of the private map sender
helpers and give movement, visibility, and lighting one documented definition.
At minimum it must consider FLAG_IS_FLOOR and gameplay opacity
(P_BLOCKSVIEW); a dedicated authored vertical-blocking flag is preferable if
roof/floor semantics cannot be expressed unambiguously.
Rules:
Ascending crosses only when an upper link exists, the boundary at the upper
cell is open from below, and the destination is legal for the complete
player object.
Descending crosses only when the current cell's lower boundary is open and
the destination is legal.
A floor is a landing surface, not something that can be crossed from below.
To reach a roof, rise through an adjacent open column and move horizontally
over it on the upper physical map.
Walls, closed doors, living occupancy, no_pass, map bounds, and multipart
collision remain authoritative at the destination. Flight bypasses terrain
classes, not solid geometry.
Missing links, map-level policy, collision, and vertical blockers produce a
clear failure message and do not partially move or spend multiple actions.
The transfer helper must perform remove/insert, map enter/leave events, map
timeouts, player map bookkeeping, LOS refresh, target/path invalidation, and
connected-map cache reuse as one operation. It must not use a generic exit in a
way that can relocate X/Y or choose an unrelated entry point.
5. Add map-level flight policy
Add authored policy such as no_flight and, if needed, a bounded flight range
or ceiling. Apply it before loading/transferring into a linked level. This is
required for interiors, puzzle/quest spaces, private maps, and deliberately
sealed structures.
Update the map checker to validate:
reciprocal vertical links and compatible coordinate/dimension assumptions;
valid flight bounds/ceilings;
an open ascent column not leading into a sealed/private level; and
intended flight test fixtures at level edges.
Do not mass-generate air maps in this issue. Add explicit air levels only where
gameplay calls for them, preserving map-author control over access and world
silhouette.
6. Preserve server-owned visibility
No new actor-visibility packet is needed. Continue to send a flyer as a normal LAYER_LIVING object on its authoritative upper map. A lower observer may see
it only when:
the relevant positive depth is linked and within the streamed window;
base 2D gameplay LOS authorizes live content at that X/Y;
vertical camera/information occlusion does not reduce the level to a
structural boundary; and
ordinary darkness, invisibility, hidden-object, and player-specific rules
allow it.
In particular, do not reveal a flyer through an unexplored wall silhouette,
roof, upper floor, secret/private level, or building cutaway. This proposal is
compatible with atrinik/client#17, but does not depend on moving camera cutaways to the
client.
Add a visible airborne status treatment for the local player and observers
without changing the sprite's authoritative map placement. The existing
per-depth projection supplies the actual height difference for observers.
7. Make selection depth-aware, but defer cross-depth combat
Extend map targets with signed relative depth. The client should gather
targets from every currently authorized depth cache and use the final painter
order/projected sprite bounds for mouse hit testing. Send depth plus X/Y/count
to the server; resolve the linked physical map and independently revalidate
viewport, LOS, vertical authorization, object identity, and visibility.
Selection, examination, names, and target UI should work for visible flyers.
For the first slice:
melee remains valid only at distance_z == 0;
ordinary floor apply/pickup/talk remains on the actor's physical level;
attacks/spells/projectiles without an explicit vertical policy reject a
target at another depth as out of reach; and
the old flying/non-flying attack-roll modifier continues to describe actors
sharing a physical level but occupying different local altitude states.
Cross-depth archery, spell trajectories, monster pursuit, pathfinding, and
vertical projectile collision need a separate combat design. They should use rv_vector.distance_z deliberately rather than silently ignoring it.
8. Resolve landing and forced falls immediately
Create one server helper that settles an actor downward through linked maps
until it finds support or reaches a configured lower boundary. Use it when:
a player lands;
the last flight capability expires/is removed;
a flying player logs in or reconnects in an invalid state;
the current air map/link becomes unavailable; or
an admin/map transition places a non-flying player over an empty level.
Reuse the existing fall damage calculation by reporting the number of physical
levels fallen, but make the operation atomic and bounded. Validate each
destination, choose a nearby legal landing square only under the existing
well-defined collision rule, and use the emergency map only for a genuinely
unrecoverable invalid save/map state.
Implementation sequence
Add server unit fixtures with a ground map, open +1 air map, solid +1
floor/roof, and -1 level. Extract shared vertical-boundary and linked-level
transfer helpers.
Split player flight capability/state; implement takeoff, landing, one-level
ascent/descent, immediate forced falling, persistence validation, map
policy, and action/path/target cleanup.
Add the vertical action and player-state protocol fields, client keybind
actions/status UI, malformed-packet checks, and ADS-2 documentation.
Extend client target caches/hit testing and CMD_TARGET_MAPXY with depth;
add server-side disclosure/range revalidation and explicit cross-depth
rejection for unsupported combat/interaction paths.
Add one debug/admin grant plus at least one intentionally balanced gameplay
source of the capability. Add a small authored flight test area rather than
modifying unrelated world maps.
Run server unit/protocol tests, both legacy builds, map checks, and the
visual matrix below; then update the owning architecture/content guidance
if the final boundaries differ from this proposal.
Acceptance criteria
A capable player can take off, move horizontally with existing flying
terrain/trigger semantics, ascend one open authored level, descend, and
land.
Incapable, grounded, paralyzed/frozen, or policy-blocked players cannot
ascend; malformed/replayed vertical commands cannot produce partial or
free movement.
Floors/opaque ceilings block ascent from below, current-level floors
block descent through them, and flight never bypasses walls, closed
doors, living collision, map bounds, or explicit no-flight policy.
A lower non-flying player sees an authorized flyer on +1/+2 with the
correct projection, name, animation, darkness, lighting, and cache
invalidation while either player moves.
Roofs, solid floors, gameplay LOS/FOW, cutaways, darkness, invisibility,
secrets, and private levels continue to prevent unauthorized disclosure.
The flying player's transition is a connected map update whose client
and server caches shift by the correct signed depth without stale or
duplicated actors.
Visible flyers can be selected/inspected by cycle and mouse targeting;
forged depth/X/Y/count combinations are rejected server-side.
Melee, apply/pickup/talk, spells, and projectiles cannot affect another
physical depth unless that individual mechanic has an explicit tested
vertical rule.
Losing flight, landing, logout/login, death, teleport, map reset/unload,
and capability changes never leave a non-flying player suspended or
inside blocked geometry; fall damage counts crossed physical levels.
Horizontal click-to-move/run never changes depth implicitly, and vertical
actions consume the intended server-authoritative action cost.
Existing flying monsters, spell effects, projectiles, FLY_ON/FLY_OFF
triggers, terrain access, and ordinary stair/exit behavior do not regress.
common/toolkit/socket.h, sender/receiver dispatch, bounds checks,
target packet, tests, client controls, map policy/checker, and doc/ADS/ADS-2 describe one coherent contract with no compatibility shim.
Validation matrix
Server tests: open/blocked/missing up/down links, destination occupancy,
reciprocal-map errors, floor landing, multi-level forced fall and damage,
capability loss, save/reload, no-flight maps, action cost, path/run cancel,
map enter/leave events, and target forgery.
Visibility/protocol tests: observers at depths -2 through +2, base LOS
blocked/unblocked, upper floor/roof/cutaway, darkness/invisibility, target
depth framing, duplicate/truncated/out-of-range payloads, and connected cache
offsets.
Client tests/manual checks: keyboard actions and status, target cycling,
projected mouse hit testing, local player centered on an upper map, observer
projection from below/above, map-edge movement, minimap, reconnect, and rapid
alternating ascent/descent.
Important
This issue is implemented in the fresh MIT-licensed Go server under the replacement program. Its gameplay and content-design decisions remain authoritative. C, CPython, classic packet, file-path, and enum details in the preserved specification are historical evidence only; do not copy, translate, or structurally port GPL implementation code.
Replacement implementation contract
Preserve discrete linked-map altitude, capability/state separation, vertical collision, and cross-depth deferrals. Use stable map/surface identities and bounded generated request/state contracts.
The server remains authoritative, consumes versioned compiled content, and exposes bounded generated Game Protocol 1 messages. Pure rules may use a specifically approved typed CEL environment. Starlark is not part of this issue unless the separate residual-scripting decision explicitly approves it.
Required verification
Preserved product/design specification and historical implementation notes
Summary
Add server-authoritative player flight by treating the existing physical
TILED_UP/TILED_DOWNmap stack as discrete altitude bands. A player whoascends moves to the linked map at the same world coordinate; ordinary players
remain on their current physical map and can see the flyer through the
already-shipped multi-level map stream whenever LOS and vertical occlusion
allow it.
This should be implemented as a focused first slice: take off, ascend, descend,
land, render, select, save/reconnect, and fall safely when flight is lost.
Cross-depth attacks and fully simulated 3D projectiles should be designed
separately rather than accidentally inheriting inconsistent 2D behavior.
Why this fits the current codebase
Most of the expensive visibility and rendering foundation already exists:
server/src/include/global.hdefinesTILED_UPandTILED_DOWN, while mapfilename coordinates and
mapstruct.coords[2]already identify physicallevels.
server/src/socket/request.c:draw_client_map2()resolves and serializes eachvisible linked map as a separate, length-delimited
CLIENT_CMD_MAPdepth.It applies base-map gameplay LOS, vertical floor/opaque occlusion, building
cutaways, and independent per-depth delta caches.
client/src/gui/widgets/map.c:map_draw_map()projects all active depths witha 46-pixel level lift and paints them in one cross-level isometric order.
TILED_UP/TILED_DOWNplayer transition already sends a signeddepth offset.
copy_lastmap()andmap_level_scroll()shift the server andclient depth caches instead of forcing a full map refresh.
map_redraw()already locates observers across linked levels usingrv_vector.distance_z, so an actor moving on an upper map invalidates thecorrect depth in a lower player's cache.
There is also an existing but narrower flight concept:
FLAG_FLYINGlets an object traverse water/fire/cloud terrain inserver/src/server/map.c:blocked()but does not bypass walls or closed doors.FLY_ON/FLY_OFFinstead ofWALK_ON/WALK_OFF, do notpress normal floor mechanisms, cannot pick up/apply ordinary ground objects,
and receive the existing combat altitude modifier.
object_insert_map(..., INS_FALL_THROUGH)stops falling when it encounters afloor or when the object has
FLAG_FLYING.Those pieces mean an actor placed on a linked upper map is already visible to a
ground observer when authorized. The missing feature is a coherent player
state and movement contract that puts the actor there.
Current gaps
SERVER_CMD_MOVEaccepts only directions0-8, and
move_ob()/object_move_to()only change X/Y or cross horizontalmap edges.
FLAG_FLYINGconflates an acquired capability with the active airbornestate. Equipment recalculation directly sets/clears it, so there is no clean
takeoff/landing toggle.
tunnel through an upper floor/opaque ceiling, and descending must not pass
through the floor of the current level.
path runs on a later insertion/move and should not leave a player suspended
after an effect expires or equipment changes.
MapCellcache, andCMD_TARGET_MAPXYsends only X, Y, and object count;the server then searches only the player's physical map.
projectile movement and much spell logic have no intentional cross-depth
trajectory policy.
cannot silently bypass indoor, quest, or private-area boundaries.
Proposed model
1. Keep physical maps authoritative for altitude
Do not add a second free-form Z coordinate to players. A player occupies
exactly one authoritative
mapstruct; its linked depth is the altitude band.Ascending or descending one band transfers the player at the same X/Y through
the reciprocal
TILED_UP/TILED_DOWNlink.MAP2_MAX_DEPTHremains a render/serialization window, not a promise that theworld has that many flyable levels. The initial implementation must use only
authored/explicitly linked maps and must not synthesize an unbounded stack of
empty air maps.
This naturally gives each observer a relative view:
The existing connected-map update and depth-cache shift should be reused for
vertical movement.
2. Separate capability from state
Introduce a distinct flight capability (for example
FLAG_CAN_FLYor aderived capability query) and retain
FLAG_FLYINGas the active airbornestate used by terrain, triggers, pickup/apply, and combat rules.
For players:
resolver and then clears the active state; and
capability and settles the player if necessary.
Existing flying monsters, spell effects, and projectiles should retain their
current behavior in the first slice. Do not make every
FLAG_FLYINGobjectstart changing physical levels implicitly.
3. Add two explicit player actions
Add client actions and default-unbound keybind commands for:
the current level; if already airborne, attempt to cross one
TILED_UPlink.there; otherwise attempt to cross one
TILED_DOWNlink.Use a dedicated, strictly framed client-to-server action such as
SERVER_CMD_MOVE_VERTICALwith a signed one-step direction. Handle actioncost, paralysis/freeze checks, movement/path cancellation, animation updates,
and rate limiting in the same authoritative layer as ordinary movement. A
text command may be useful for debugging, but should not be the gameplay wire
contract.
Expose
can flyandcurrently flyingin player state updates so the clientcan disable actions and display an unambiguous status indicator. Horizontal
click-to-move and run paths remain on the current physical map in this slice;
they must never auto-ascend.
4. Make vertical collision directional and shared
Move the reusable vertical-boundary predicate out of the private map sender
helpers and give movement, visibility, and lighting one documented definition.
At minimum it must consider
FLAG_IS_FLOORand gameplay opacity(
P_BLOCKSVIEW); a dedicated authored vertical-blocking flag is preferable ifroof/floor semantics cannot be expressed unambiguously.
Rules:
cell is open from below, and the destination is legal for the complete
player object.
the destination is legal.
To reach a roof, rise through an adjacent open column and move horizontally
over it on the upper physical map.
no_pass, map bounds, and multipartcollision remain authoritative at the destination. Flight bypasses terrain
classes, not solid geometry.
clear failure message and do not partially move or spend multiple actions.
The transfer helper must perform remove/insert, map enter/leave events, map
timeouts, player map bookkeeping, LOS refresh, target/path invalidation, and
connected-map cache reuse as one operation. It must not use a generic exit in a
way that can relocate X/Y or choose an unrelated entry point.
5. Add map-level flight policy
Add authored policy such as
no_flightand, if needed, a bounded flight rangeor ceiling. Apply it before loading/transferring into a linked level. This is
required for interiors, puzzle/quest spaces, private maps, and deliberately
sealed structures.
Update the map checker to validate:
Do not mass-generate air maps in this issue. Add explicit air levels only where
gameplay calls for them, preserving map-author control over access and world
silhouette.
6. Preserve server-owned visibility
No new actor-visibility packet is needed. Continue to send a flyer as a normal
LAYER_LIVINGobject on its authoritative upper map. A lower observer may seeit only when:
structural boundary; and
allow it.
In particular, do not reveal a flyer through an unexplored wall silhouette,
roof, upper floor, secret/private level, or building cutaway. This proposal is
compatible with atrinik/client#17, but does not depend on moving camera cutaways to the
client.
Add a visible airborne status treatment for the local player and observers
without changing the sprite's authoritative map placement. The existing
per-depth projection supplies the actual height difference for observers.
7. Make selection depth-aware, but defer cross-depth combat
Extend map targets with signed relative depth. The client should gather
targets from every currently authorized depth cache and use the final painter
order/projected sprite bounds for mouse hit testing. Send depth plus X/Y/count
to the server; resolve the linked physical map and independently revalidate
viewport, LOS, vertical authorization, object identity, and visibility.
Selection, examination, names, and target UI should work for visible flyers.
For the first slice:
distance_z == 0;target at another depth as out of reach; and
sharing a physical level but occupying different local altitude states.
Cross-depth archery, spell trajectories, monster pursuit, pathfinding, and
vertical projectile collision need a separate combat design. They should use
rv_vector.distance_zdeliberately rather than silently ignoring it.8. Resolve landing and forced falls immediately
Create one server helper that settles an actor downward through linked maps
until it finds support or reaches a configured lower boundary. Use it when:
Reuse the existing fall damage calculation by reporting the number of physical
levels fallen, but make the operation atomic and bounded. Validate each
destination, choose a nearby legal landing square only under the existing
well-defined collision rule, and use the emergency map only for a genuinely
unrecoverable invalid save/map state.
Implementation sequence
floor/roof, and -1 level. Extract shared vertical-boundary and linked-level
transfer helpers.
ascent/descent, immediate forced falling, persistence validation, map
policy, and action/path/target cleanup.
actions/status UI, malformed-packet checks, and ADS-2 documentation.
CMD_TARGET_MAPXYwith depth;add server-side disclosure/range revalidation and explicit cross-depth
rejection for unsupported combat/interaction paths.
source of the capability. Add a small authored flight test area rather than
modifying unrelated world maps.
visual matrix below; then update the owning architecture/content guidance
if the final boundaries differ from this proposal.
Acceptance criteria
terrain/trigger semantics, ascend one open authored level, descend, and
land.
ascend; malformed/replayed vertical commands cannot produce partial or
free movement.
block descent through them, and flight never bypasses walls, closed
doors, living collision, map bounds, or explicit no-flight policy.
correct projection, name, animation, darkness, lighting, and cache
invalidation while either player moves.
secrets, and private levels continue to prevent unauthorized disclosure.
and server caches shift by the correct signed depth without stale or
duplicated actors.
forged depth/X/Y/count combinations are rejected server-side.
physical depth unless that individual mechanic has an explicit tested
vertical rule.
and capability changes never leave a non-flying player suspended or
inside blocked geometry; fall damage counts crossed physical levels.
actions consume the intended server-authoritative action cost.
FLY_ON/FLY_OFFtriggers, terrain access, and ordinary stair/exit behavior do not regress.
common/toolkit/socket.h, sender/receiver dispatch, bounds checks,target packet, tests, client controls, map policy/checker, and
doc/ADS/ADS-2describe one coherent contract with no compatibility shim.Validation matrix
reciprocal-map errors, floor landing, multi-level forced fall and damage,
capability loss, save/reload, no-flight maps, action cost, path/run cancel,
map enter/leave events, and target forgery.
blocked/unblocked, upper floor/roof/cutaway, darkness/invisibility, target
depth framing, duplicate/truncated/out-of-range payloads, and connected cache
offsets.
projected mouse hit testing, local player centered on an upper map, observer
projection from below/above, map-edge movement, minimap, reconnect, and rapid
alternating ascent/descent.
./build.sh atrinik-server,./build.sh atrinik, targetedCTest suites (then
./build.sh check), focused map checks, clang-format, andgit diff --check.Out of scope
camera.
the first change.
vertical pursuit, or 3D pathfinding.
or map-access policy.
presentation independently.