Mode X in Turbo Pascal, Part 4: Tilemaps and Streaming

Mode X in Turbo Pascal, Part 4: Tilemaps and Streaming

A renderer becomes a game when it can show world-scale structure, not just local effects. That means tilemaps, camera movement, and disciplined data loading. In Mode X-era development, these systems were not optional polish. They were the only way to present rich scenes inside strict memory budgets.

This final Mode X article focuses on operational structure: how to build scenes that scroll smoothly, load predictably, and remain debuggable.

Start with memory budget, not features

Before defining map format, set your memory envelope:

  • available conventional/extended memory
  • VRAM page layout
  • sprite and tile cache size
  • IO buffer size

Then derive map chunk dimensions from those limits. Teams that reverse the order usually rewrite their map loader halfway through the project.

Tilemap schema that survives growth

A practical map record often includes:

  • tile index grid (primary layer)
  • collision flags
  • optional overlay/effect layer
  • spawn metadata
  • trigger markers

Keep versioning in the file header. Old DOS projects often outlived their first map format and paid dearly for “quick binary dumps” with no compatibility markers.

type
  TMapHeader = record
    Magic: array[0..3] of Char;  { 'MAPX' }
    Version: Word;
    Width, Height: Word;         { in tiles }
    TileW, TileH: Byte;
    LayerCount: Byte;
  end;

Version fields are boring until you need to load yesterday’s assets under today’s executable.

Camera math and draw windows

For each frame:

  1. determine camera pixel position
  2. convert to tile-space window
  3. draw only visible tile rectangle plus one-tile margin

The one-tile margin prevents edge pop during sub-tile movement. Combine this with clipped blits from Part 2 and you get stable scrolling without full-map redraw.

Chunked streaming from disk

Large maps should be chunked. Load around camera, evict far chunks, keep hot set warm.

A simple policy works well:

  • chunk size fixed (for example 32x32 tiles)
  • maintain 3x3 chunk neighborhood around camera chunk
  • prefetch movement direction neighbor

This is not overengineering. On slow storage, missing prefetch translates directly into visible hitching.

Keep IO deterministic

Disk access must avoid unpredictable burst behavior during input-critical moments. Two rules help:

  1. schedule loads at known frame points (post-render or pre-update)
  2. cap max bytes read per frame under stress

When a chunk is not ready, prefer visual fallback tile over frame stall. Small visual degradation is often less disruptive than control latency spikes.

Practical cache keys

Use integer chunk coordinates as cache keys. String keys are unnecessary overhead in this environment and complicate diagnostics.

type
  TChunkKey = record
    CX, CY: SmallInt;
  end;

Pair keys with explicit state flags: Absent, Loading, Ready, Dirty. State clarity is more important than clever container choice.

HUD and world composition

Render world layers first, then entities, then HUD into same draw page. Keep HUD draw routines independent from camera transforms. Many old engines leaked camera offsets into UI code and carried that bug tax for years.

You can validate this quickly by forcing camera to extreme coordinates and checking whether UI still anchors correctly.

Failure modes to test intentionally

Test these early, not at content freeze:

  • camera crossing chunk boundaries repeatedly
  • high-speed movement through dense trigger zones
  • partial chunk read failure
  • map version mismatch
  • missing tile index fallback path

Each one should degrade gracefully with explicit logging. Silent corruption is far worse than a visible placeholder tile.

Cross references for full pipeline context

These pieces together describe not just rendering, but operation: startup profile, page policy, draw order, and asset logistics.

Closing note on Mode X projects

Mode X is often presented as nostalgic low-level craft. It is also a great systems-design classroom. You learn cache boundaries, streaming policies, deterministic updates, and diagnostic overlays in an environment where consequences are immediate.

If this series worked, you now have a path from first pixel to world-scale scene architecture:

  • memory model
  • primitives
  • sprites and timing
  • streaming and camera

That sequence is still useful on modern engines. The APIs changed. The discipline did not.

Treat your map format docs as part of runtime code quality. A map pipeline without explicit contracts eventually becomes an incident response problem.

2026-02-22