| Latest version | 14.367.1.1 |
|---|---|
| Minimum Core | 14.367 |
| Compatible Core | 14.367 |
| Last updated | 11 hours ago |
| Created | 11 hours ago |
| Authors |
|
| Languages |
English |
| Systems | All systems |
| Project source | Project URL |
| Report bugs | Bug tracker URL |
| Changelog | Changelog URL |
| License | License URL |
Walls And Vision Elevation Sampling adds height-aware walls, three-dimensional visibility sampling, cover, peeking, and surface-aware sight to Foundry Virtual Tabletop.
WAVES is currently an alpha release for Foundry VTT v14.367. Use in an active campaign is not advisable.
WAVES is system-independent at its core. Its dnd5e integration recognizes the prone and hiding statuses.
Uses Foundry's center-based visibility with height-aware walls. This conservative compatibility mode does not calculate sampled cover.
Tests multiple source and target points in three dimensions. A target is visible when at least one valid ray is not blocked by a wall or sight-blocking surface.
WAVES mode provides:
Target-specific visibility is authoritative. The rendered canvas mask is an approximation and may not represent every sampled ray.
Wall Configuration includes Wall Bottom and Wall Top fields. A wall blocks a ray only when the ray crosses it within that interval. The bottom is inclusive and the top is exclusive.
Blank bounds mean negative or positive infinity. A wall with both bounds blank is vertically unbounded. Level assignments remain a separate Foundry constraint; a wall applies across all Levels only when its Level assignment is empty.
Changing wall heights updates the Foundry Level assignments overlapped by the range. Changing Level assignments also updates the height range.
New wall height controls newly placed walls:
The GM-only Toggle new wall height mode keybinding defaults to Alt+W and displays the selected behavior in a notification.
Existing imported, migrated, or macro-created walls are not rewritten automatically. A GM can derive WAVES heights from existing Level assignments:
await waves.syncWallHeightsFromLevels(canvas.scene);
Existing WAVES flags are preserved. To replace them:
await waves.syncWallHeightsFromLevels(canvas.scene, { overwrite: true });
Walls without Level assignments remain unchanged because an empty assignment means all Levels.
WAVES uses TokenDocument geometry. Actor size and Actor height are not consulted.
width and height define horizontal occupied space.depth defines vertical size in grid units.elevation defines the bottom of the token's vertical volume.In dnd5e, prone uses half the normal vertical volume for visibility sampling.
In WAVES mode, Token Configuration provides optional overrides for eye height, vertical eye movement, and vertical eye positions. A blank override uses the current world setting, shown by the Automatic placeholder.
| Visible target samples | Result | Bonus |
|---|---|---|
| 0% | Total cover | — |
| Up to 25% | Three-quarters cover | +5 |
| More than 25%, up to 50% | Half cover | +2 |
| More than 50% | No cover | +0 |
Any visible sample makes the target visible. Total cover prevents it from being attackable through the WAVES API.
WAVES currently reports cover and its suggested bonus through the API only. It does not apply attack modifiers, conditions, or other automation. Integrations with systems or automation modules such as Automated Conditions 5e or Midi-QOL may be added later.
Peeking adds target-specific origins around nearby blocking cover, including limited over-wall and under-wall positions.
attackableInTurn checks.A Region with a sight-enabled Define Surface behavior acts as a horizontal sight-blocking plane at the behavior's surface elevation. WAVES evaluates crossings between Levels and refreshes when relevant Regions or Region behaviors are created, updated, or deleted.
A Region elevation range does not give the surface physical thickness.
Foundry's rendered light polygons remain two-dimensional. WAVES can recover a geometrically visible target reached by an active light source through height-valid light rays even when Foundry's rendered light shape is blocked at another elevation.
Recovered targets use distinct outlines:
Foundry detection modes remain authoritative for hidden, invisible, and special-sense behavior. Sense All may reveal a token even when waves.measureVisibility() reports ordinary sight as blocked.
Movement walls are ignored when their vertical range does not overlap the moving token's current vertical volume. Optional green dashed overlays identify height-passable walls for the controlled token. Secret doors are never exposed to non-GM users.
WAVES retains Foundry's path constraint, snapping, surfaces, movement actions, and movement costs.
Synchronize token Level with elevation prompts when an elevation change crosses into another Foundry Level. Confirming changes both elevation and Level; declining cancels the movement or update.
When Elevation Level Change is active, WAVES disables its synchronization handling and warns the GM.
All WAVES settings are world settings.
| Setting | Default | Purpose |
|---|---|---|
| New wall height | Viewed Level | Select viewed-Level or unbounded bounds for new walls. |
| Visibility mode | Foundry | Select Foundry center visibility or WAVES sampling. |
| Automatic peeking | Off | Permit eligible target-specific peeking. |
| Target area | Whole occupied space | Sample the full occupied area or a smaller body area. |
| Viewing position | Center | Look from the center or multiple occupied-space positions. |
| Eye height | 85% | Default eye position within token depth. |
| Vertical eye movement | 10% | Normal movement above and below eye height. |
| Vertical eye positions | 3 | Number of sampled vertical eye positions. |
| Show height-passable walls | On | Draw green dashed movement overlays. |
| Synchronize token Level with elevation | Off | Prompt when elevation crosses a Level boundary. |
| Performance debug | Off | Log aggregated timings to the browser console. |
The API is available as game.modules.get("waves").api and globalThis.waves.
To copy an issue-report payload, open the browser developer console, control one source token, target one other token, and run:
copy(JSON.stringify(waves.getIssueReportData()))
Alternatively, control exactly two tokens. WAVES uses them in their control order as source and target.
const result = waves.measureVisibility(sourceToken, targetToken, {
type: "sight",
includeSurfaces: true,
usePeeking: true
});
The result includes visible, detected, attackable, attackableInTurn, percentage, cover, coverBonus, sample counts, and peeking information.
For visual and console diagnostics:
waves.measureVisibility(sourceToken, targetToken, {
showTestSamples: true,
usePeeking: false
});
This temporarily draws successful and blocked rays and logs one JSON object. Other API functions include:
waves.getVisionOrigins(token, options);
waves.getWallHeightBounds(wall);
waves.hasBlockingWallCollision(origin, destination, type);
waves.registerOptionalResolutionAdapter(adapter);
waves.syncWallHeightsFromLevels(scene, options);
waves.testVisibility(source, target);
Include reproduction steps, whether other modules were disabled, and the issue-report payload. The payload contains active module versions, scene geometry, WAVES settings, and the visibility result, so review it before sharing. Use waves.measureVisibility(source, target, { showTestSamples: true }) only when temporary ray visualization is also useful.
To install this package, open your Foundry Setup screen and navigate to your Module tab and click the Install Module button.
From there, you can either search for the package unique name: waves or copy its manifest URL:
And paste it to the input box at the bottom of your window.

You can install this package directly to your Forge account.