Jump to content

Tickled_Pink

Members
  • Posts

    8,605
  • Joined

  • Last visited

Blog Entries posted by Tickled_Pink

  1. Tickled_Pink
    I just had to blog this. But spoiler alerts are due. So, if you haven't watched Seasons 3 or 4 of The Last Kingdom and intend watching it, feel free to come back later.
     
    I love historical shows and movies. An extreme example of what I've witnessed in The Last Kingdom was the Starz show, Black Sails. This was where the writers came up with a historical setting and shoehorned characters from books and actual historical pirates into the show. It was never intended to be historically accurate but a rough representation of what pirates dealt with and how life was for them in somewhere like Nasau.
     
    The Last Kingdom is based on a book. Fair enough. So you don't expect 100% accuracy but, given that it's based not just on the life of Uhtred but also those of actual historical people who lived at that time, you'd expect them to take more care with historical facts because people are going to look them up.
     
    It was nice to see that the Welsh, for once, weren't forgotten. If all you ever learned was what you saw in movies, you'd swear that it was just Scotland, England and Ireland in this part of the world. But let's get to the elephant in the room. The fact that they have completely screwed over the timeline.
     
    They seem to have gone to some lengths to get the Saxon aristocracy right.

    Alfred died in 899. He was succeeded by his son Edward, who would have been 25 at the time. That all seems to check out judging by the apparent age of the actor who plays him. But it seems to point to the fact that, certainly where the English are concerned, the writers were trying to stick to history as much as possible while keeping the story going. In fact, they even put in the story about his son, Aethelstan being possibly illegitimate. That is historically accurate in that nobody has ever known for certain. They managed to intertwine that into the story.

    All good so far. They do play fast and loose with Aethelred of Mercia. By the time he died in 911, he'd been on the throne for 30 years, so the actor is too young but at least the timing of his death is kind of within an acceptable range. The suspicions of the Mercians towards Edward's intentions for their lands in the show is also based on historical fact. Edward did eventually take over Mercia, but not for another 15 years.

    They're trying to be accurate-ish, but when it came to Wales, everything went out of the window.
     
    The Hywel that Wessex went to for aid was undoubtedly Hywel Dda (Hywel the Good). This was confirmed after a couple of episodes where he tells his right-hand man, Rhodri, that he's going on pilgrimage. Again, that was historically accurate because he did, becoming the first Welsh ruler to go on pilgrimage and return. When I heard Ealhswith ask Father Pyrlig to go to Hywel, I knew that it had to be Hywel Dda because if there's one thing the show does, is pick up on some of the better known characters from that time. But when I saw him, I had a feeling something was a little off. He was too old.
     
    In fact, the real Hywel was about 6 years YOUNGER than Edward, not 30 years OLDER!! When we're first introduced to the Welsh when Pyrlig is confronted by a couple of guards, the name Deheubarth appears across the screen to tell us all where they are. This show is currently set at some point between 899 and 905AD. Deheubarth didn't even exist. It wouldn't exist for at least another 15 years when Hywel created it after joining up two kingdoms he ruled over. What's more, Pyrlig would have had to cross at least one other Welsh kingdom to get to Hywel's domain because he had no lands that bordered the English kingdoms at that time.

    He ruled from around 918 and, contrary to his depiction in the show as being fiercely independent, he and his brother (joint ruler) submitted to Edward. He became sole ruler in 920 and expanded his domains to cover almost all of Wales.

    The shift in the timeline also leads to another huge inaccuracy. When Edward does die in 924, it's his alleged illegitimate son, Aethelstan, who takes over. Hywel became close friends with him. If Hywel was as old as he's depicted in the show, he'd probably be dead by the time Edward dies and would possibly never have even met Aethelstan.

    I think the problem for the writers was that they wanted to introduce a strong character who was well-known. Unfortunately, this was really a time when there were in fact few Welsh rulers who's names had resonated through the centuries. Rhodri Mawr (Rhodri the Great) died 25 years before Alfred. A better character for them to use would have been a guy called Anarawd, Rhodri's son and King of Gwynedd at the time of the events depicted in the show. If they had been clever, they could even have intertwined him with Aethelred's story because he invaded Gwynedd and had his ass handed to him by Anarawd. Anarawd also had to deal with an attack by Danes from Ireland in 902. Gwynedd's lands also bordered Saxon lands.

    So, given that I've just finished watching an episode where Hywel discovers that the Danes are coming for him from Ireland, I think what's happened is that the writers took Anarawd and replaced him with Hywel, changing the location and Hywel's age as well in the process. Few people have even heard of Anarawd, even though his father remains one of the most revered Welsh leaders. And we have places named after Hywel.

    I don't mind inaccuracy for the sake of pushing along a story but this was just too much.
  2. Tickled_Pink
    Anyone who's played the original will know how eerie the game looks. The Arboreal Trees are the main feature of the game. They are the items that spread infection across the land. They look great on the ST and Amiga. They grow then sink into the ground, before growing again at an adjacent square.

    Having played around with some Gear VR games I had noticed a few games that had minimalistic, yet effective, untextured polygon graphics. And as I'm still trying to grow my confidence with 3DS Max, I wasn't that keen on designing my own trees. I didn't want to make a direct 3D copy of the originals.

    A couple of weeks ago I came across a possible solution - voxel trees. The idea came from this 3DS Max Maxscript tutorial on YouTube.

    https://www.youtube.com/watch?v=ZoIY5lT6IV4

    I took the ideas in this and created my own version in C#. It doesn't work in quite the same way. The result is less perfect and yet seems more fitting in that the trees grow in a more erratic fashion, which is something you might associate more with something that's diseased. Also, instead of trees sinking into the ground, they crumble from the top down after a few seconds. The pieces (voxels) then sink slowly into the ground they land on as they fade. Wherever a piece lands on, that square will become infected and one or more new trees will grow in those new infected areas.

    One minor gameplay change that will come from this is that disease is likely to spread faster across the landscape than in the original.

    The tree test works fine but at the moment it's not working when I place the tree in a level. Hopefully that shouldn't take too long to fix.


    Something that does work and, as expected, didn't take very long to do was the energy and timer bars. The design of those is likely to change by the end and they will need to be completely redesigned for VR otherwise they will be uncomfortable as they'd be right in the player's face, as it were.
  3. Tickled_Pink
    Cleared out my blog - except for one entry. Decided that it was time to start afresh. This is going to be a dev-only blog from now on.

    For the past couple of weeks I've been working on remakes of Sentinel and Archipelagos in Unity. Sentinel turned out to be quite a tricky game to write, not least because I have to go by YouTube videos as I've never played it. The feature of the two games is that the landscapes are pseudo randomly generated. Something I've never been confident with is level design. But both Sentinel and Archipelagos manage to create their levels on the fly. I've also realised that there are many games that create levels and data using pseudo-random generation.

    The one I've known about for years is, of course, the original Elite. But if you have a game where there are seemingly endless levels then chances are there's pseudo-randomness going on. The beauty of pseudo-random generation is that you can create entire levels and worlds that look the same from game to game but take up very little memory.

    Creating Sentinel's levels has been quite tricky and I haven't quite got it right yet. Archipelagos, on the other hand, has been much easier. However, I am cheating a little in that there won't be endless levels. The game's maps have been created randomly using a Perlin Noise generator. I put it onto a large 2D texture which was saved out into a .PNG file. I then opened it up into Photoshop and extracted some of the more interesting 'island' formations manually. These were then saved into their own 512 x 512 & 1024 x 1024 images.

    The results haven't been ideal. Perlin noise tends to produce rounded and quite uniform hills and troughs. There's no jaggedness at all. However, it's probably good enough for now. If I can figure out a better way to generate the map then I'll do it later. The way the code has been written allows me to use any map, so long as it uses the same basic colours for the 'tiles'.

    And this is another issue.

    Originally the game was going to use tiled maps. That would be the obvious approach, right? The problem is that, at the moment at least, the largest texture size (the texture holding the 2D map of a level) is 1024 * 1024 pixels. If I was to convert the map to a set of polygons laid out in a tiled way, ​that would equate to over a million polygons! However, Unity works a little differently to some game engines in that it insists on turning polygons into triangles. Not sure if that's optimal for GPUs. It's useful if you've been too lazy to optimise a 3D model, but if you've optimised things into quads then Unity's way of handling polygons doesn't look too hot. Either way, in our case that equates to more than 2 million triangles. Not good - especially if you're aiming to target mobile devices. And with this remake, I am ... and in particular Gear VR.

    So how to go about optimising it? Every tile has to be clickable. If I made every tile one of half a dozen coloured planes then I could attach a trigger to each one. That would be the simplest way to do it.

    But no ... too much stress on the GPU.


    The solution was to use a single large plane and place the texture map onto it. The main problem then was to convert the coordinate systems. The plane would use a 3D coordinate system with the centre being 0, 0, 0. The 2D texture map's zero location is at the top left [No. No it isn't. See the entry further up]. I was trying to place objects using a pseudo-random generator but they weren't locating properly. Took me a good few hours to realise what I was doing wrong ... I wasn't taking into account the different coordinate systems. Stupid! Stupid! Stupid!

    After writing a couple of 2D/3D conversion methods in my C# code, it worked like a charm [again. No it didn't. It looked like it was but Unity's 2D texture coordinate layout was screwing things up for me]. I was able to get objects to place on each level properly without any manual input from me. All thanks to pseudo-random number generation. And it would work exactly the same way every time the game was run.

    Another beauty of the way the system works is that to change the colour of a 'tile' (remember, the tiles aren't actually polygons), I need to just change the colour of the appropriate pixel in the level's texture map. In Archipelagos, the trees spread infection across the land. When a tree changes position, I just have to get the tree's new location, convert it to 2D coordinates and change the colour of the pixel the tree is now on. It's a lot less work for a mobile GPU than having to handle more than a million polygons.

    I'll stick up some in development screenshots in my next post.

  4. Tickled_Pink
    As previously mentioned, I cheated a bit with the map for each level. Originally I was going to create endless levels by using a pseudo-random generator and a Perlin noise generator. The problem, however, was that I couldn't figure out (was too lazy to figure out) how to restrict the number of islands on a level.

    When the map was generated there was no way to figure out where an island's edge was. I probably could do it by tracing around the sand coloured pixels. That will have to come later if I decide to go down that route. It also needed to be on a large enough texture map to ensure that there were enough islands that didn't 'fall off' the edge of the map.

    This is what the final HUGE map looked like.



    Using Photoshop I then cut away the more interesting islands and put them into smaller textures for use in the game.




    You will notice the problem with uniformity around the edges. Ideally that's not what I'm looking for. Perhaps an extra layer of noise could be added to the edges to reduce the roundedness.

    So what does this look like in the Unity editor? Unity didn't import the textures quite right to begin with but the following settings fixed it.



    The crucial settings here were to change the Texture Type to Advanced and then set the image format to 16 bits. Without it, it was importing the images as Sprites and compressing the texture. This was causing some pixels to be miscoloured and when displayed in the editor or in-game it was trying to blend each pixel with its neighbours.

    Oh yes - I also had to enable the Read/Write option, otherwise I wouldn't be able to modify the texture on-the-fly.


    In the editor I created a plane the same size in Unity units as the texture was in pixels (a 512x512 texture = 512x512 unit plane) and placed the appropriate texture on it. And bingo, this was the result.




    The red line you see is an early attempt to add a bit more atmosphere by adding a red fog, which will increase in density as the land becomes more infected. The Unity fog effects aren't perfect so this might get dropped.
  5. Tickled_Pink
    Movement has been working fine on desktop, except I haven't implemented a way to turn around yet. All it does is allow players to click somewhere on the land ahead of the camera to move to that point. I decided that I'd allow free movement. Just simplified things for me. It means that the player doesn't end up in the middle of a square, as with the original. You can move wherever you want, so long as it's a valid area.

    As this is intended primarily for VR I decided to concentrate on getting the head tracking working. I had made a tentative attempt with another project (a Vector-based Battlezone-style blaster) a few weeks ago but couldn't get it working. Not sure what I did wrong at that time. However, looking at the documentation this time round revealed that in a VR project, I can't move the camera directly. I have to attach it to a parent object and then apply all transformations to that. Perhaps that's where I went wrong with the previous project.

    Anyhow, Unity handles head tracking automatically on the object containing the camera. Pretty neat stuff. I tried it out and it worked first time (something unheard of if you're a programmer ). However, it did reveal an issue with the resolution. Despite the S7 having a fairly decent resolution (significantly better than the Oculus DK2), there was a fair amount of texture 'jitter' towards the horizon. It made squares look as though they were jumping around a bit and wasn't very comfortable to look at. So I re-enabled the red fog and that fixed the problem by hiding far pixels and the jumping squares. The fog looks a little better than I expected. It looks quite eerie to see the obelisk outlined in the fog in the distance.

    So, ETA? Could be as little as 2 weeks at this rate.
  6. Tickled_Pink
    I have just spent a frustrating 4-5 days trying to figure out why movement wasn't working properly. I've reverted the project to a Windows game while I develop the mechanics. Clicking the mouse while the pointer's on a tile will move the camera to that location. Moving the pointer to the left or right edge of the screen will rotate the camera. However, I noticed that it didn't seem to be detecting the correct tile type when it came close to the sand tiles. Sometimes it was detecting water or was detecting sand a couple of squares before it should. I couldn't figure it out for days.

    So I eventually ran a few tests. I suspected that it was an issue with Unity. I coloured in the corners of the texture map to Red, Green, Yellow and Black then used the Texture.GetPixel() method to return the pixel on each corner. I was expecting 0,0 to be the top left of the texture. But no. It turned out that in Unity 0,0 is the bottom left!!

    Another issue with Unity was that the plane to which the texture was applied needed to be rotated by 180 degrees along the Y axis.

    Once I finally had all this figured out, it was easy but this is one area that needs to be better documented.

    One advantage of this coordinate system, however, is that it greatly simplified the 2D->3D and 3D->2D conversions. I moved the plane so that the bottom left sat at 0,0,0. This meant that positive X in 3D space equalled positive X in 2D space. Similarly with the Z and Y.

    So now it works. Finally! Jeez!
  7. Tickled_Pink
    As usual, my code was getting a bit messy and a bit long. So I ended up spending 2-3 days refactoring the code and splitting it up into more classes. As a general rule, classes and methods should contain as few lines as possible. I'm more of a brute force coder but I'm trying to change the habit of 20+ years' with this project ... hell, I've even added documentation to my code!


    Another quirk I discovered in Unity was the way that Textures are instanced and referenced. A cool feature of Unity is that you can declare an object as public and then in the editor's inspector, drag and drop that object from your assets directly into the class. It's brilliant but it can lead to lazy coding. I've certainly been guilty of that. Can't be bothered writing a piece of code to load an asset at runtime? Hell, just create an array of objects and drag'n'drop every asset into the array. It also leads to over-reliance on this lazy method without actually thinking about what goes on under the hood.

    A case in point was the way that Unity handles textures. The game relies heavily on pseudo-random numbers to generate and place objects on each level. What should happen is that because a pseudo-random number generator generates the same set of numbers it places the objects in exactly the same place each time the level is loaded. However, what I hadn't realised was that whenever an infected square was added to the texture in-game, it was actually being saved onto the original texture file. What this meant was that each time the texture was loaded, it already contained 'infected' pixels. The pseudo-random generator looks for green tiles to 'infect' at the start of each level. So it couldn't choose these already 'infected' pixels again and therefore chose different pixels, which were then also added to the texture file.

    The solution was to create a copy of the texture map. To ensure that it wasn't just creating a reference to the original texture map, I had it create the new working texture map and then copy the original map pixel by pixel. It doesn't create any noticeable slowdown during startup. So now, whenever changes are made to the map during gameplay, it's made to the working map rather than the original that's loaded into the game.


    Further progress has also been made to the placing of new land. That's now working 100%. If a player right clicks on sand, it creates grass. If a player clicks on water or an infection, it creates sand. So the basic game control mechanics are now all working on desktop. Now it's time to move onto the energy and timer bars.
  8. Tickled_Pink
    It's been a while since I did anything with this project. I've been working on a couple of simpler mobile games (one loosely based on the Amiga game, Oxyd). I'm going to try to put a few days' worth of work into this one this week.

    The latest is that the game itself is working fine. After the previous update I went back to debugging the issues with the tree placement in the game world. Took me a while to realise where I had gone wrong but I eventually fixed it. For now, however, it's running exclusively as a desktop program. As I suspected, the number of polygons is an issue. The tree creation code needs to be refined somewhat to reduce the number of tiny voxels at the ends of the branches, which are just causing additional overhead without providing any real benefit. When I last tried it with Gear VR, it broke the VR because the Samsung S7 couldn't keep up with having to draw that many polygons twice (once for each eye).

    There needs to be some additional optimisation as well in Unity. It seems to me that it's currently still trying to 'draw' each polygon when they're not visible on-screen or occluded by the fog. The VR was breaking even when the trees weren't in view.

    So what's been done so far?

    Static Landscapes created (needs to be changed to randomly generated landscapes to allow unlimited levels).
    Main obelisk added.
    Red fog added at the distance
    Mouse movement added

    Immediate to-do list:

    Add stones
    Add plants
    Allow player to click on stones and plants.


×
×
  • Create New...