it has just occurred to me that the algorithm matches the plot of the novella: in the story, Triax adapts the natural cave system to his own evil plans, whereas the map generation system allows local manipulation of a "naturally" generated map.

Regarding "It's almost surprising that there are no other such instances of object 'echoes' like this, given how they're generated." -- actually, I think there are. Based on a hunch, and a 30-year old vague memory of some things disappearing after blowing up a different thing, I did a test this morning:

- Go to the button we've been talking about, the right by the door / slimes puzzle and fireball firing gargoyle.
- Blow up the gargoyle head (not too hard to set it on fire with its own fireballs by hitting it with the icer).
- Go directly up, through the wind cave, to where the other gargoyle head is.
- Oh look, it's gone!
- Unconfirmed but I bet the two gargoyle heads are aliased.
- Do they both share an x co-ordinate? I think they might? That shouldn't be strictly necessary to get an alias, but it does appear to be something that happens!

It should be pretty easy to write a program that searches all x,y map co-ordinates for object aliases, including ones that do not share an x co-ordinate.

I'm interested in writing it but I likely can't get to it in the next couple of days. I wonder if someone will beat me to it

scarybeasts wrote:Do they both share an x co-ordinate? I think they might? That shouldn't be strictly necessary to get an alias, but it does appear to be something that happens!

Actually, it looks as if it's exactly that. Looking again at determine_background, any map tile index from 0-8 has the potential to contain a background object. Background object indices then seem to get looked up from the x coordinate (within a range - background_objects_range - derived from the tile number) - and if there's no match, there's no background object.

Seems to me that aliasing will only occur when two or more map tiles with the same x coordinate yield the same value between 0-8, but maybe I've missed something?

It should be pretty easy to write a program that searches all x,y map co-ordinates for object aliases, including ones that do not share an x co-ordinate.

I'm interested in writing it but I likely can't get to it in the next couple of days. I wonder if someone will beat me to it

I doubt I have the time either for a while, but it'd be nice to confirm.

Yes, I was going to mention those two gargoyles but you beat me to it. They're definitely on the same x coordinate, I checked the map last night. So this thread has also ended up answering the question of why (as mentioned in the official solutions) blowing up one gargoyle also destroys the other!

I now see the map with new eyes. I used to think that the little bushes hanging onto the side of vertical tunnels were explicitly placed there as items 'on top of' an empty map square, but now I can see that the map square 'is' the leaf, as it were. Now I can see that every square contains one and only one tile, and yet somehow the whole thing fits together and feels 'real'.

It would be fascinating to interrupt the map generation algorithm at various stages, and then create a shot of the map at that point, so you could see how the algorithm builds up the map. (I might have a go at some point, as my first serious attempt at 6502 coding and debugging.)

VectorEyes wrote:It would be fascinating to interrupt the map generation algorithm at various stages, and then create a shot of the map at that point, so you could see how the algorithm builds up the map. (I might have a go at some point, as my first serious attempt at 6502 coding and debugging.)

Here's the thing which is so astonishing about Exile: the map isn't really "built up" at all.

Often, in modern games with generated content, they start off with a blank canvas, and start to build hills, lakes, roads, bridges, etc using a seeded random number sequence (i.e. one which can be reproduced consistently). With this approach, the world is truly built up, and the algorithm may be influenced by what exists nearby. If you were to cut the generation short, you'd end up with an emptier world.

Exile doesn't do that. Exile just has an enormously complicated function f(x,y) which simply says: given x and y, tell me which tile number is here. The function knows nothing of its neighbouring tiles; it has to be able to give a result purely from the x,y inputs. In the program earlier, I just showed the first stages of the algorithm which instantly categorise an x,y as "empty", "mapped" or "generated", but for generated tiles, this just does more calculations on the input to obtain a tile index.

This is a very difficult way to do procedural generation, and Exile is all the more remarkable for having done it so well!

On the subject of Exile - what would have to be done to make the game scroll smoothly? The jerky-scrolling has never annoyed me, but I was thinking that with new add-ons like the VideoNula, would it be possible to recode the game to smooth things out?

trixster wrote:On the subject of Exile - what would have to be done to make the game scroll smoothly? The jerky-scrolling has never annoyed me, but I was thinking that with new add-ons like the VideoNula, would it be possible to recode the game to smooth things out?

This is something I've wanted to do with games like JCB DIgger. It's fairly easy to slot the VideoNuLA "fractional" horizontal scrolling alongside the CRTC scrolling (I do this in the Shadow of the Beast demo) but you'd need to find some space for the extra code + variables. This might be tricky in a game like Exile that uses every bit of memory.

Happy to take a look at it or advise others as I'm not overly familiar with Exile.

trixster wrote:On the subject of Exile - what would have to be done to make the game scroll smoothly? The jerky-scrolling has never annoyed me, but I was thinking that with new add-ons like the VideoNula, would it be possible to recode the game to smooth things out?

I always assumed the jerky scrolling was down to frame rate more than anything else, since the game doesn’t run at 50Hz. I guess as it’s doing a one CRTC character hardware scroll in MODE 2 this is 2 pixels horizontally but 8 pixels vertically so is always going to be quite coarse.

trixster wrote:On the subject of Exile - what would have to be done to make the game scroll smoothly? The jerky-scrolling has never annoyed me, but I was thinking that with new add-ons like the VideoNula, would it be possible to recode the game to smooth things out?

I always assumed the jerky scrolling was down to frame rate more than anything else, since the game doesn’t run at 50Hz. I guess as it’s doing a one CRTC character hardware scroll in MODE 2 this is 2 pixels horizontally but 8 pixels vertically so is always going to be quite coarse.

You might be right, in my last play around with Exile I used an emu rather than hardware and ran it at between x1.25-x2, it was lovely!

I always assumed the scrolling style was because the player can move at finer increments than the hardware scrolling, i.e. horizontally and vertically by 1 pixel. That said, when you get up to speed walking along a horizontal passage, the screen does in fact scroll smoothly with you.

Worth noting that, in the Amiga version, the scrolling isn't continuous either even though it probably could be. The camera is kind of 'looser', only starting to move once you've covered a certain distance. It's actually more natural than a camera that stays rigidly fixed on the player.

It wouldn't be impossible to hack in some smooth scrolling, using rupture and the VideoNuLA horizontal offset, but remember that the water level is rendered according to the raster time from the vsync, so this calculation would have to change. And I don't think it'd be really easy to do, even if you could find some spare space to do it in, and a spare VIA timer to do the screen splitting for the vertical scroll...

1) Aliased stone door.
The stone door you'll recognize is (5c, c0) which is the third stone door in a row that you use the cannon turret to blow up late in the game, near the maggot machine. It's aliased to a door directly above that closes off an empty alcove. When the turret blasts the third stone door, the alcove door does also disappear.

- 47 (stone door x2) (5c, b8) (5c, c0)

2) Another aliased stone door.
(7f, c3) is the horizontal stone door by the red acid drip where you create the coronium rocks to blow open the rune door. It's aliased to another horizontal stone door that is inaccessible and buried in rock. I haven't tested whether blowing up the accessible one makes the buried one disappear but surely it would.

- 89 (stone door x2) (7f, 94) (7f, c3)

3) Couple of aliased bushes / nests.
I confirmed these are real.
The bush is the bush on the way to the cannon RCD where the invisible cyan frogman pops out at you. Normally, you waste that guy before you encounter the other bush which would then be empty because the aliased state is "number of frogmen left in nest". But I hacked my x,y position in the debugger to land straight in the aliased bush and hey presto, out pops cyan frogman!
The nest is a huge nest of yellow maggots and the alias is real: empty the nest above with the blaster and the nest directly below is also empty.

4) Buzz ball nests.
This is a treat: earlier in the thread, daveb noted there's a nest in a place you can never reach:https://www.youtube.com/watch?v=tjZphdFGZ_g
That's actually an aliased nest for the buzz ball nest by the slot where you have to throw fluffy through to push the button to turn off the magenta death ball turrets.

- 9f (ball nest x2) (a5, 6b) (a5, e7)

5) No-effect aliases.
Probably an artifact of squeezing out every last memory byte, but there are some objects which share the same data pointer but where they are different types. Typically, one of the types is "immutable", e.g. a brick, so there's no observable effect to sharing data state.

- cc (turret / water) (a6, 69) (e1, 73)

Full alias list below (minus data pointers >= 0xe8 because there are tons of aliased leafs)

scarybeasts wrote:Here are the extra ones I found, i.e. new very minor Exile secrets?

Well done on compiling this list! You're certainly drilling down into the inner workings with this.

scarybeasts wrote:1) Aliased stone door.
The stone door you'll recognize is (5c, c0) which is the third stone door in a row that you use the cannon turret to blow up late in the game, near the maggot machine. It's aliased to a door directly above that closes off an empty alcove. When the turret blasts the third stone door, the alcove door does also disappear.

scarybeasts wrote:2) Another aliased stone door.
(7f, c3) is the horizontal stone door by the red acid drip where you create the coronium rocks to blow open the rune door. It's aliased to another horizontal stone door that is inaccessible and buried in rock. I haven't tested whether blowing up the accessible one makes the buried one disappear but surely it would.

- 89 (stone door x2) (7f, 94) (7f, c3)

Yes, destroying one destroys both. Video evidence to come later!

scarybeasts wrote:3) Couple of aliased bushes / nests.
I confirmed these are real.
The bush is the bush on the way to the cannon RCD where the invisible cyan frogman pops out at you. Normally, you waste that guy before you encounter the other bush which would then be empty because the aliased state is "number of frogmen left in nest". But I hacked my x,y position in the debugger to land straight in the aliased bush and hey presto, out pops cyan frogman!
The nest is a huge nest of yellow maggots and the alias is real: empty the nest above with the blaster and the nest directly below is also empty.

scarybeasts wrote:4) Buzz ball nests.
This is a treat: earlier in the thread, daveb noted there's a nest in a place you can never reach:https://www.youtube.com/watch?v=tjZphdFGZ_g
That's actually an aliased nest for the buzz ball nest by the slot where you have to throw fluffy through to push the button to turn off the magenta death ball turrets.

- 9f (ball nest x2) (a5, 6b) (a5, e7)

paulb pointed this out to me a couple of days ago and we experimented a little to see if the upper nest/portal is generated or part of a custom map area. It turns out to be custom made - not present if those are disabled in the map generation routine.

I'd need to re-read the description of how aliasing happens to understand this, but does this mean that all tiles with the same type on a given map column would behave the same way? I wonder if the authors realised that the generator had created a tile of the same type elsewhere in the column. I like the way that this limitation in the engine leads to the creation of these secrets. I wonder how much the authors were aware that this was happening!

The fireball-shooting gargoyle below the rune door aliases a gargoyle deeper in the caverns. Destroying one causes the other to be destroyed. In this case, destroying the first one is easier because the second is in a windy area. This explains why I remember encountering the lower gargoyle many years ago when playing through to completion: I hadn't destroyed the first one before progressing to the final area.

The fireball-shooting gargoyle below the rune door aliases a gargoyle deeper in the caverns. Destroying one causes the other to be destroyed. In this case, destroying the first one is easier because the second is in a windy area. This explains why I remember encountering the lower gargoyle many years ago when playing through to completion: I hadn't destroyed the first one before progressing to the final area.

Ah, nice one. I knew "blank" must be some form of error as I wrote it. Also sorry for the confusion on the third stone door by the plasma cannon turret. I saw that was missing in the big map rendering and meant to mention it.

I've never seen background objects 'popping' into existence like in your video! Is that some other weird thing to do with aliasing, or is this just something which sometimes happens on the Electron version?

It's not usual on the Electron version, though I believe I have seen this sort of behaviour before when experimenting with lots of collectable objects, like grenades. I think it's just the engine catching up after a teleport event.

If there's a way of taking a snapshot with jsbeeb, patching it, and loading it back in then I could share what I did with Elkulator. I see that a save state facility is on the to-do list...

Just wanted to say that all the responses in this thread surpassed my wildest hopes. It's great to know once and for all what that bloody button does, and it's been a fascinating insight into how Exile works!

Rich Talbot-Watkins wrote:If it were up to me, I'd have a separate Exile subforum!

Without wanting to trigger a mega-thread, VectorEyes & I were discussing what an Exile 2 might look like, perhaps if it was Master only... or whether the original game is considered the beautiful pinnacle of 6502 game engineering (on the BBC platform at least?!) Not that I am volunteering to code it mind..!

I struggle to imagine how it could be much better than it already is. However I do have a practical suggestion, which is whether it could be ported to the 6502 second processor. This would free up a lot of memory which could be used for more sound samples perhaps?

jms2 wrote:I struggle to imagine how it could be much better than it already is. However I do have a practical suggestion, which is whether it could be ported to the 6502 second processor. This would free up a lot of memory which could be used for more sound samples perhaps?

That's an interesting idea, whether it might be possible to run the physics simulation / object update on the scond processor to speed up the game itself. Might be more challenging to divide the work as clearly over the Tube as Elite, say.

In terms of having extra RAM, anything on the host side (or SWRAM perhaps) could be used to store sprites in 4bpp (MODE 2 native) rather than 2bpp which ~may~ speed up the screen plotting routines (although no guarantees as Exile code is tighter than tight.)

I must admit, I have been very gently mulling over the idea of actually trying to make a sequel. The problems are that 1. I know virtually nothing about Beeb coding (yet!), 2. I have virtually zero free time and 3. It's difficult to think of improvements that wouldn't also somehow subtract from the purity of the gameplay.

The game engine is already so up against performance limits, and the gameplay so well-suited to the engine, that if you added features you'd probably have to take something else out. One could imagine things like Thrust-like carrying heavy objects, different densities of fluids, all kinds of stuff, but I wonder whether they'd really improve the gameplay or not.

I've also been wondering about making small improvements to the existing game. VideoNULA support, perhaps? Make the water slowly become a darker blue the deeper you get. Subtly change the colours based on which part of the map you're in, etc.

Oh, and get rid of the two empty key slots on the Loader status screen that can never be filled with keys!

Similary after the Galaforce nula16 version I did I had a play with the exile code but just didn't give it enough time,
I've to have also been thinking about a) chaning the seed for a new map and b) changing the blanking and forced parts as shown by Richard.

When originally designed do you think the guys had some sort of editor to specify forced and clear areas on the map? If we had something like that, creating new puzzles scenarios would be a doddle.