Progress on Future
City has been slowed by web-site and release preparation work at the
moment. I've split my time about 2:2:1
between Web site, Future City, and Alpha Release preparations.
January push towards Web Site, City demo, and Alpha Release. |
This split in
attention as well as the pressure of the approaching alpha release means blog
posts have been slower forming. Let's
just squeeze out a quick update on the Future City progress...
Future City
At the moment I've
been focusing on the support of variable elevation across the city, with each
city block having its own height.
Example of blocks with shared connectivity but height discontinuities |
This
feature results in rather complicated requirements at the interfaces between blocks
as well as complicating the process of sub-dividing up the space within
them. As such, it's been quite slow
progress working out (a) exactly what is required, (b) how to perform this, and
(c) how to implement this.
Requirements
Based on the previous connectivity work which sub-divided the city up into districts/zones
and finally blocks, we have already decided on what the connectivity between
each block looks like.
Now we need to
decide on what the content of the block should be such that it is possible to
guarantee that adjacent, separately generated content aligns properly,
functions as a seamless transition, and looks plausible.
Inputs
We have the
following information about each block boundary:
- Block location/bounds/size.
- Access along each side (left/right of opening within any barrier present).
- Follow the underlying landscape shape, or both share flat ground level at a given height.
- Connectivity via each side (to the outer most city sides).
- Variation seed to drive arbitrary design decisions.
Outputs
From this we need to
populate the block with rectangular sub regions. The main problem we are trying to solve here
is to transition from a boundary with zero, one, or two accessibility
transitions along each side into spaces for content to go that all have single
accessibility along each side, these being simpler requirements to
satisfy. Thus the outputs are of the
form of Content Spaces with the following properties:
- Bounds size, orientation and location
- Surface height within the space (or if we are to follow the landscape)
- Is it an interfacing piece, i.e. responsible for handling transition to neighbouring block interface? (Edge - one interface along block boundary, Corner - two interfaces along block boundary, Side - three interfaces along block boundary)
- If not an interface, then an interior piece, with same type all round (flat or landscape)
- For each boundary interface: Specific flat elevation or landscape following. Do we 'own' this side (are responsible for interfacing geometry). Is this a barrier, i.e. will access be blocked? Is there a barrier to the left/right that we may need to provide transition geometry for?
Test Rig
Since there are a
lot of combinations to test in forming this system it is worth generating a set
of 'unit tests' with clear visualisation of the inputs and outputs. By creating a hierarchy of test procedures we
can quickly generate tests for all the major side and access combinations.
- Ownership - all, none, adjacent, opposite
- Surfaces - all landscape, all flat, mixture
- Access - Closed corners, all open, all closed (bar one), some on left, some narrow, mixture
Unit tests for a lot of the block interfacing cases |
For cases where a
specific issue is being resolved there is the option to switch out all but one
test scenario.
Example test rig showing corner results produced |
Algorithms
I spent a lot of time in Excel playing with block boundary examples and possible approaches.
Playing with block algorithm ideas in Excel |
From this I've come up with a lot of ideas, but they seem to be heading
towards this sequence of calculations:
First pass at the content space and interfacing algorithm |
There are bound to
be some changes as implementation proceeds, but this is a good starting point.
Lists
Structured Data
The amount of
structured information and variability in generated output finally became too
much and I had to stop to add some functionality to help support this. Previously where several properties about a
single thing needed to be conveyed through several procedures it had to be
passed individually, and explicitly.
This leads to this specific flavour of spaghetti:
A specific flavour of spaghetti: arrays of connections |
The algorithms that
were forming to perform the interfacing and content-space generation were
heading towards an awful lot of this.
From the requirement analysis above we can see each block has at least
seven properties that go together, and each potential output content space has
at least six.
Traditionally these
would be encapsulated in structures, where a single type is used to express an
explicit collection of typed data. This
is something that Apparance will natively support in the future, but it's quite
a lot of work, especially on the tooling side where composition/decomposition
of structures needs to be handled elegantly.
Variable Quantities
Another aspect of
the block interfacing implementation problem is that there are several places
where we need to pass a variable number
of structures. At the moment there is no
concept of this and we would have to pass a fixed (maximum) number of
structures (as individual properties) along with an additional flag expressing
whether it was in use. This forms a
very, very unwieldy situation where all sorts of operations, such as combining
two variable sized collections, become incredibly complicated, expensive and
error prone. We really need some form of
list or array to handle this.
Solution
Both these prospects
are really going to cause too much of a headache to work on the already complex
problem, so we need support to help this.
Looking at other
language for inspiration, we find that both these problems can be addressed by
using lists of dynamically typed objects.
If a list happens to contain all the same type, then it is effectively a
traditional list or array, i.e. a variable sized collection. If a list happens to contain a fixed number,
of different typed elements then it can be used as a structure. Adding support for lists as just another base
data-type to Apparance is fairly straight-forward and then means we can have
lists of lists, or put another way, lists of structures.
Implementation
The List data type
was added along with an initial set of basic operators to support what we would
need, as follows:
- Append - take a list and add another element (any type).
- Get - index a list, returning the element value (any type).
- Set - replace a value at a specific index with a new value (any type).
- Count - query how many elements are in the list.
Part of the
implementation that took a bit of effort was that I wanted type information to
be maintained with them as the lists are constructed. With this, a lot of validation can be
performed during synthesis that would catch problems that would otherwise be
very difficult to diagnose and have potential to crash the engine.
Whilst a bit tricky
to implement, lists are proving very useful so far and make a lot of the block
interfacing problem much more pleasant to work with.
Passing structures and collections around as lists |
I am even now using them in the web site
building procedures for all sorts of things.
Progress
I'm about half way
through the Block Boundary -to- Content Space processing system and have
promising results so far.
Some of the content space generation results so far |
I'll post more
results as I progress. In the mean-time
I have an Alpha Release to get out!
No comments:
Post a Comment