More about lazy vals - makingthematrix/gailibrary GitHub Wiki

In the first version of GAI lazy vals will not be allowed to use other lazy vals. This is because lazy vals asking for lazy vals might lead to circular calls inside one cell (lazy val „a” needs lazy val „b” while „b” needs „a”), or across many cells (a laz val from one cell asking for a lazy val from a referenced cell, which in turn asks for the original lazy val). But I think the concept of lazy vals is a pretty nice way to describe the AI logic, and disallowing them to reference one another might be too limiting.

Let’s consider an alternative way to set the „player_in_room” lazy val. Instead of checking in the position graph if it contains the player reference, a more natural solution would be to rely on „player_visible”. This is also a lazy val, but it does not rely on any other lazy val, so calling it is safe. Furthermore, the NPC could also check „player_visible” of other NPCs in the room, thus simulating a wireless connection between them – headphones in the helmets, for example. When one of the NPCs sees the player, it warns the others. (There’s also another possible approach – more about it later).

So, in a slightly later version of GAI, it would be useful to allow at least this: A lazy val may declare what other lazy vals it requires and the configuration limits how far we can go. Maybe we want to allow only situations such as this one. But maybe we want allow access to twice-removed lazy vals too. Or thrice-removed. But as long as it is a finite number, we can be sure we will not be running in circles.

In fact, in later develoment, I might be interested in writing an actual system diagnostics. It would be based on macros. In the debug mode macros would register what lazy vals, temp vars, etc., are called by and how many times. This way we could get rid of „requires” and „sets” fields in functions and replace it with something less error-prone.

GAI.register_function(„player_in_room”, requires = „player_visible”, f = { 
  npc => npc(„player_visible”) || npc.refs.exists(„player_visible”) 
})