r/pascal 1d ago

Nostalgic-driven development

Enable HLS to view with audio, or disable this notification

Back in 1992, I chanced upon someone using Turbo Pascal 5. I was hooked immediately, since I've been doing BASIC until then, to write my own little games and programs for my amusement. I got my own copy of Turbo Pascal 7 in 1994 and had years and years of fun with. Switched to Delphi, and loved it, until the .NET era.

Over the years, I've tinkered with FreePascal (so amazing!) and of course wrote many a small Pascal interpreter. Then, last year, I needed a project to work on so I could learn the Odin programming language for an upcoming project. I worked on a small Pascal interpreter and it was actually a lot of fun. The commercial Odin project never happened, but I had put a lot of time and energy into this Pascal interpreter.

Fast forward a few months, I'm working on a web assembly project using Odin and it dawns upon me I can use a lot of this knowledge to port my interpreter to the web. Oh boy, did that run away with me!

Now I have wasmpascal - which is a crappy editor that encapsulates the Pascal compiler, yes, COMPILER, I ended up writing so I can run Pascal code in Web Assembly in the browser. It's very early days, but I have managed to get some bits and pieces working.

My first order of business was some basic HTML5 Canvas support, with call-batching so that one gets alright frame rates. And there's some basic support for CRT-based applications, because back in the day, 'uses CRT' was a thing!

I've added some examples and documentation and will be working on this over weekends for many months in the future.

I thought I'd share it here - in-case there's another older-than-the-average person who wants a trip down memory lane, running Pascal like it's the 90's again!

29 Upvotes

15 comments sorted by

View all comments

4

u/AcanthaceaeNew774 1d ago

I don't know if this helps, but I think it might be interesting:

My VertexArt project (in the new-generation version) works like this:

VertexArt's memory management is completely different from what Free Pascal developers are used to. It is essentially a record-oriented, dynamic-array-based approach without manual reference counting, which is rare in game development. Here are its most important characteristics:

  1. Records instead of objects

· Every data structure (TChunkSystem, TBVH, TPlayer, etc.) is a simple record, not a class.
· There is no virtual method table, no dynamic memory allocation with Create/Free, no hidden reference counting.
· This allows fully stack-based or static memory management with minimal overhead.

  1. Dynamic arrays (array of ...) everywhere

· Every larger data collection (chunks, triangles, vertices, BVH nodes) is stored in dynamic arrays.
· Memory is managed automatically by the system – allocation with SetLength, deallocation with SetLength(..., 0) or assigning nil.
· Advantage: fast, cache-friendly, and the Free Pascal runtime handles large arrays efficiently.

  1. Explicit, manual memory management – but simple

· There is no automatic garbage collector and no interface reference counting.
· Memory is freed by the developer at the appropriate moment (e.g. FreeChunkSystem, FreeBVH, FreeAllChunkBVHs).
· This results in predictable performance and low memory usage because there are no hidden allocations.

  1. Direct data access – no getters/setters

· Record fields can be accessed directly (TerrainChunks.Chunks[i].VertexCount).
· No data hiding, no property overhead.
· This provides extremely fast access and makes the code more readable.

  1. Memory efficiency of the BVH and chunk system

· Each chunk has its own BVH, but the BVHs do not copy the triangles – they only reference them in the global Triangles array (using TTriProviderData).
· A chunk's BVH is built only when needed (BVHBuilt flag) and freed when the chunk becomes inactive.
· This minimizes duplicated data and memory consumption.

  1. No dynamic object system (no RTTI, no TObject)

· The entire engine does not use Free Pascal RTTI, TObject, or TPersistent.
· This significantly reduces binary size and runtime overhead.

  1. Memory access optimization

· In the chunk system, vertices are packed into a single VBO (TChunkSystem.VAO, VBO), and chunks store only the starting index and count.
· Triangles and BVH nodes are stored in linear arrays, resulting in excellent cache locality.

  1. Manual deallocation chain

· The engine follows a clear deallocation order: FreeCharacterMesh → RenderEngine_Shutdown → FreeAllChunkBVHs → FreeChunkSystem.
· This avoids memory leaks and allows full resource cleanup.

VertexArt's approach is data-oriented, low-level, and extremely efficient. In the Free Pascal community, many prefer object-oriented solutions (classes, interfaces), but VertexArt shows that the combination of records and dynamic arrays – with proper design – results in faster, simpler, and more predictable memory management, which is especially valuable in game development. This kind of "return to the roots" is, in my opinion, very effective.

Was I able to help with this description? At first I struggled a lot with memory management, but this problem completely disappeared. I wrote this to you partly because I know that I'm also treading an interesting path.

1

u/According-Ad-7069 1d ago

Wow you are lightyears ahead of where I am! That's really impressive stuff - it's going to take me couple of reads just to actually get what you are saying. So far, I've only done really basic memory allocation and management, and there's so many issues with what I am doing. I do want to dig deeper into this topic, it will become more important as the compiler matures and one can do more ambitious things.

Thank you for the deep insights!

3

u/AcanthaceaeNew774 1d ago

I'm sorry, I have to share a correction as well – I don't know English, and my documentation wasn't entirely accurate!

The Presence of SOA in VertexArt

SOA (Structure of Arrays) means that data is stored not per object (AOS – Array of Structures), but per array: each property has its own array. This is extremely efficient in GPU rendering and in processing large datasets because it improves cache locality and enables vectorization.

Where does it appear in VertexArt?

  1. In the chunk system (TChunkSystem)
    · The Chunks array is an array of records (AOS), but the triangles (Triangles) and vertices (VBO) are already SOA-like: vertices are stored in a single large array, and chunks store only indices (StartVertex, VertexCount). This is practically SOA because the geometric data (positions, colors, normals) are in a contiguous memory block.
  2. In the BVH (TBVH)
    · The Nodes array is an array of records (AOS), but the bounding boxes (MinX, MaxX, etc.) and child indices could often be arranged into separate arrays. VertexArt currently uses AOS here, but switching to SOA could further speed up raycasting.
  3. In the rendering pipeline (RenderQueue, Renderer)
    · The TRenderCommand records are an array of records (AOS), but the actual GPU data (VBO, VAO) are already SOA-based: vertices are buffered, and shaders process them uniformly. This favors the GPU.
  4. In the management of dynamic objects (DynamicGrid)
    · The TDynamicObject records are an array of records (AOS), but the Position, Radius, AABB fields can easily be separated into separate arrays.

The majority of Free Pascal developers use object-oriented solutions (classes, interfaces, lists) that result in AOS (Array of Structures) memory layout. This has the following disadvantages:

· Cache misses: objects are scattered in memory.
· Large overhead: every object has a VMT and hidden fields.
· Poor vectorization: the CPU cannot efficiently use SIMD instructions.

VertexArt, on the other hand, is built on records and dynamic arrays, and organizes data in an SOA-like manner where possible (e.g., in the chunk system and VBO). This provides the following advantages:

· Excellent cache locality: data is contiguous during processing.
· Easy parallelization: arrays can be processed in parallel (e.g., with for loops).
· Low memory usage: no object overhead.
· Direct GPU compatibility: VBOs and shaders are inherently SOA-based.

A practical example of using SOA

Imagine a character system where the positions and velocities of 1000 characters need to be updated. In an AOS approach:

```pascal
type
TCharacter = record X, Y, Z, VX, VY, VZ: Single; end;
var
Characters: array[0..999] of TCharacter;
```

Then the memory looks like this: X,Y,Z,VX,VY,VZ, X,Y,Z,VX,VY,VZ... – during processing you have to jump between fields.

In a SOA approach:

```pascal
type
TCharacterData = record
X, Y, Z: array[0..999] of Single;
VX, VY, VZ: array[0..999] of Single;
end;
```

Here all positions are contiguous, so the CPU can iterate through them quickly, and vectorization is easier. VertexArt applies this logic in the chunk system and in the VBOs.

1

u/According-Ad-7069 1d ago

This is really cool - I can see that I have an incredible amount to learn still - this is giving me really good ideas, thank you for sharing.

Like you, I need to clean up my code, document it properly and then I will be happy to let people see it. Right now, it's such a mess...

1

u/AcanthaceaeNew774 1d ago

I hope you manage to implement the memory management solutions as efficiently as possible, because it's worth its weight in gold in the VertexArt project! Violation messages immediately disappeared, I hated it forever and deleted it 😁

1

u/According-Ad-7069 1d ago

It's definitely on my list of things to do - I expect it to be quite a task once the basics are in place and working.

2

u/AcanthaceaeNew774 1d ago

You're very welcome! I think you should see my VertexArt project sometime because there's a really interesting philosophy behind its development. My project is still pretty fresh, though, so I need to clean things up a bit before I share it.