The Spatials V3 devblog 2016-02-22

Internal development notes, very slightly cleaned up and commented a week later.

TL;DR: AI for station robots, solid click testing code, begin implementing final info inspector

Another slow week, but things are starting to pick up steam.

The last update saw the addition of helper robots for the station sim. This past week the AI was added to them.

- service droid AI

Thanks to the quickly maturing entity-component engine of V3 adding the initial work of adding the AIs was trivial. For example this is the “maker” procedure for the hauler robot:

(define-mod-export (make-station-robot-hauler world e obj x y a)
    (make-npc-object world e (npc-objects-by-name "droid_cargo") x y a)
    (civ-add-components e (civ-named "Spatials"))
    (make-vulnerable e hp: 100)
    (make-flee e)
    (ecs-make-add-component e PhysicsComponent_Kind
        #@standardSpeed 2.0
        #@maxSpeed 10.0)
    (ecs-make-add-component e MaxCarryComponent_Kind
        #@maxCarry 20)
    (ecs-make-add-component e worker-component
        'one (list delivery-job-component))
    (ecs-make-add-component e ReadyComponent_Kind)

Maker procedures are called when a new entity needs to be spawned in the world. They work by adding components to the passed entity e. make-npc-object is a helper procedure which sets up basic NPC components, like sprite poses, the position and size component, etc. In this case droid_cargo is the name of an autoprobed sprite collection. V3 makes extensive use of autoprobing file names in order to build sprite poses and animations, avoiding a lot of manual work.

After initializing the entity with basic information, it is then enriched with more components so it will be handled by various AI systems. civ-add-components makes the robot aligned with the Spatials civ. make-vulnerable adds components relating to combat hit points and will also make the entity a target for any enemies that cross its path (along with its civ alignment). Some very basic components are directly added to the entity without using helpers. For example PhysicsComponent_Kind is re-instanced here in order to increase the entity walking speed, and a new MaxCarryComponent_Kind is created to increase the carrying capacity and make the hauler robot more useful.

The bulk of the work was about fixing subtle bugs in the existing engine code for all those systems. For example the job system uses a boundary check to detect when an entity has arrived to the desired spot for perfoming the job. The hauler robot is faster than other entities and it overshoot just a little that boundary, failing the check.

- final object click testing
	pass obj ref to display in DisplaySystem
	nodes inherit the tag
	this way plain 2d clicking is possible
	add click query to DisplaySystem, with z sorting
- on-screen extents calc in DisplaySystem
- use the real on-screen extent rect for drawing a selection box at Z -1
- click selection: fix focus cycling when matching more than one entity
	clear ref tags from selection rect node
- draw better 9s rect for selection

Click testing for mouse selection was next. It’s something that may appear trivial, but given how flexible is the V3 view code when it comes to entities, it was quite a challenge. First it was required to set some kind of tag on the drawing primitives in order to mark them with the originating entity (if any). This new feature allowed for both a click test that can return the list of clicked entities for a given position, and also code to calculate the on-screen boundaries of an entity (which can be drawn using one or more display systems, where each system can use one or more primitives, in any number of Z layers with any kind of transformations, pivots and displacements).

Focus cycling was also fixed, so now on V3 mouse selection works with the natural on-screen order. There’s no need anymore to guess to click on the floor, and overlapping entities just cycle the selection when clicked repeatedly.

- enable autosizing by default for gui-v/h
- allow autosizing for gui-render
- start final impl for info panel
	info inspectors decoupled from into tool code
		expose an aspect, if selection matches, they are called and must return a model hash for a widget to display
		(info-tool-register-inspector aspect drawer), callable on file load, no need to wait for rules setup
New selection reticle

With selection being much more robust it was time to being the final implementation of the info panel inspector panels. A simple and very flexible system has been choosen. Any mod can register at any time a new inspector panel by calling info-tool-register-inspector and pass a component aspect for matching entities, and a procedure to be called. When the info tool selects an entity it will test it against all the registered panels aspects and when it matches, it will call the procedure, which will return a GUI widget. For example here’s a simple panel that detects when the selection is an officer:

(define (officer-inspector e)
	(gui-label :text "YEAH it's an officer"))
	(ecs-aspect must: (list OfficerComponent_Kind))