“No GenAI was used in the preparation, planning or creation of this work. [AIAS Level 1]”
This is a dev log for the "ZapAndLap" video game assessment.
The purpose of this task was to trace Canterbury's streets for racetrack options.
For reference I took a screenshot from Google Maps to trace. (Photogrammetry from Google Earth was too complicated)
This was just a start, because then we had hours of Unreal Engine lecture tutorials. (I may need to learn C++, because nodes don't share the same rules as Python, C#, GDScript, or GameMakerJunk. (Non transferrable skill, unless you go to develop in Scratch))
I think the tracing is alright, though I may need to put more polygons into the round-abouts. I will also need to look at heightmap data; in fact, I could probably put real heightmap data into blender and move all of the nodes accordingly.
I shall continue working.
Today I finished the road layouts for the tracks.
For reference I used the image in Blender, but later I used 3D Google Earth for reference on height.
I think this turned out well, hopefully this will feel like the 64 bit console from a company that shall not be named for legal safety reasons. I am also hoping that the roads will be fun to drive on, and will work well for scale in Unreal Engine.
I started by tracing all of the larger/ more prominent roads that could work as a track from an isometric top view. After that I traced the thicker smaller roads from the arterial roads that could help make the track feel more like a city. After that I downloaded a heightmap of Canterbury from a world heightmap website called "Tangram Heightmapper" which I then applied to a plane that I scaled to the parameters of the image and subdivided a bunch. I did this by using a displacement modifier, creating a new texture, and setting the texture as the image. I set the heightmap height to 0.25 and set the colour to a transparent blue to help me see the roads beneath. Then I moved every vertex of the roads to fit the terrain; train tracks and highways were moved up in pairs of two vertices to keep them flat, because they move terrain rather than move around terrain. Lastly I joined all of the roads together to cut out the tracks later.
Next I will probably build up the terrain and buildings.
The purpose of today's task was to create some of the environment to hide the void.
I used Google maps to reference where the trees, gaps, and buildings are.
It seems alright at this moment in time, but I am not sure if I should leave gaps where gaps are in real life, because in games like Mario Kart the level is surrounded by walls.
I just manually extruded edges and snapped edges to the road. By the end of the day I was reccomended a Blender add-on called Blender-OSM/ Blosm, but it turns out that you need an API key from Google that requires your bank credentials for 3 months free; so I'll continue doing it manually. This may take longer than I first anticipated.
The purpose of this task was to continue modelling the walls and terrain to make a nice looking environment.
For reference I used the no-clip website to compare my model with games from the real 64bit console.
I think that the day was fairley successful. It's cool to see a landscape forming rather than just some walls; and I got quite a noticable portion done. Ther may be too many pligons per frame visible, so I may need to reduce that in order to make it feel more 64-like.
First I created an Unreal Engine project for the game in order to test out the track feel; I also created a material without backface culling in order to see the undersides of bridges. After that I started by surrounding a large plot of land off of the motorway by what will be walls of foliage. Then I started creating faces for the ground in triangular shapes because that's sort of what the terrain looks like in Mario 64 games, except mine is less uniform. I would try to match the vertices to the terrain to mimic the real-life topology. To hide the fact that I have walls instead of foliage I decided to add roofs to the clusters, but then I noticed that it looks more like something from the Wii than the 64. In the future I may need to have planes to try and hide the backs of the walls; like in "Beetle Adventure Racing!". Later I placed the terrain into Unreal Engine to test the viewpoints, which looked fairly nice, but then I encountered that the player character would fall through the ground. So I opened the landscape 3D model file to try and re-enable the "complex to simple" collision, but I noticed that some of the faces were transparent; that's when I realised than my normals were flipped the wrong way. So I went into Blender, enabled the face orientation view, selected the inverted faces, and flipped the normals.
I will continue building the terrain, in the future I may need to add footpaths for realism.
I did a little more of the track, and then we started making mood boards and Trello boards.
For the track I sometimes snap extruded verticies to the road to give me a line to create a face.
I did a little work on the track(s), but it wasn't very significant.
I finished (for the most part) modelling the terrain. I then applied materials to different parts, thinking about what textures could only need horizontalness and therefore I could stack vertically. I also fixed some N-gons by selecting "Faces by Sides" "Greater Than 4".
I still need to UV map the future textures to the walls and such, but I'll do that once the textures are available. I will also need to have some planes to hide the back-faces instead of topping them off, to make it more N64 than Wii.
I also briefly made the grass texture with hair particles on a plane, and an area light in a lightless void. I think I'm going to need to change the lighting because it is lighter in the middle; so, kind of a donut light would be better.
I also added a bunch of specific tasks to Trello to coordinate my team; a list of various assets.
I started by updating the grass texture to use a torus as a light source, and then I created a concrete texture using noise maps and displacement.
Before Donut.
After Donut.
After that I placed the updated road mesh into Unreal Engine, and flipped a bunch of normals, patched a couple holes, and re-assigned a couple materials.
And finally, I UVd one grass section. First I looked at how Mario Kart 64 did it. Then I unwrapped everything as a blob, but I could see the tesselation; so I conformally unwrapped every triangle. But then I realised that Mario Kart 64 has tessellation across the individual triangles; I don't know how I'm going to do that.
In the future I'm going to need to make the materials tesselate better (maybe a light sphere), make them tesselate across the individual triangles (scale the triangle in the UV viewport and eyeball it proportionately), and start working on making the game mechanics so that the game sort of exists in three weeks.
I started by making the grass more tessellate-able. First I tried to put all of the colour variation in the centre and "bleach" the edges; but that didn't help much, it was still an obvious tessellation. Then I had a look a what "Mario Kart 64" and "Beetle Adventure Racing" did; it wasn't clear at first, but then I broke it down to there being more "white noise" and less shape in the textures. So I made my material more noisy, and made the two noise textures be the same scale at different locations for randomness. To finalise the material I reduced the contrast between the two noise texture to create a softer grass texture. I then exported the PNG at full (lossless) compression and 8-bit colour depth; I chose 8-bit because although it's a 64-bit processor I want the textures to be less advanced; I reckon there's no perceivable difference though.
Then I did the concrete texture by similar principles.
After creating the materials I marked the tasks as green (for finished) in Trello.
After there is some concept art of the game, I will be able to use it to guide my art to fit future textures better with the science-fiction theme.
In the future I will also need to combine the metal wall texture and future guard rail texture into one texture, which will mess up the UV map a little, which is why I won't be making it for those two elements right now. But I did do the UV map for the grass and concrete quickly since they tessellate in all directions; if I were to UV map it better I would have to manually scale every face and eyeball it.
I then created a mesh to look like a weathered metal panel with bolts. And I added a weathered-looking material to the panel; initially I was thinking about finding a decal of dirt streaks, but I decided against it because I would need to find a creative commons licenced image.
I decided to make a hedge texture for the leafy parts of the tracks.
For reference I used an image from Google maps of a leafy road in Canterbury.
First I made a plane with hair particles to make the grass. Then I added some sausages for the trunk and branches. I also added a blob for the canopy. Later I made two leaf variations and applied them to the blobs with geometry nodes, allowing the blobs (except the trunk and branches) to disappear. To colour the leaves I wanted to have a material that got lighter the smaller the leaves were, but I couldn't find anything that worked online, and I wasn't going to try a python script. So I settled for just random colour to random leaves which I learned from a YouTube video. I placed an orthographic camera and a sphere with an emissive material, and when I was happy with the tweaking I rendered the scene.
The result gives me mixed feelings because on its own the texture looks fine, and fairly realistically noisy; but when applied to a wall it very obviously tessellates. I tried to work around it by stretching it over the entire face; I also because UV mapped the walls that way because UV mapping them all at once makes the texture tesselate vertically, which it shouldn't do.
In the future I may need to remove the trunk and ask Mike for his expert UV opinion.
I decided to finally build the vehicle mechanics. So I looked for a tutorial on making a race-car, and after a few attempts I found a tutorial series by a YouTube channel called "Ryan Laley" where he builds a vehicle from scratch. (Unlike all of the other tutorials that use the vehicle template). (It was a pretty good tutorial series too, he didn't explain things as if I've never used a computer before).
First we made a brick that hovers with ray-casting. Then we added acceleration and reverse-acceleration. After that we added steering, and this is where I started adding things that weren't specified in the tutorial.
I didn't like the tank-steering (I was fine with the vehicle rotating on the spot, but I didn't like how it steered backwards) so I added some node logic so that if the acceleration was less than 0, the steering would invert. For the steer-inverting code I ended up just copying everything for each output of the branches, because you can't do math directly with branches; I know there's a better way of doing it, but for now this works.
After that I started tidying up the code a little, adding message containers explaining what the things appear to do so that I could remember in the future, and to hopefully make Troy's life easier. I also added variables in some areas for ease and maybe future utilisation in external factors.
Then I decided to try and make a drift mechanic, and after some time trying I made the vehicle steer three times more sharply and slow down significantly faster when holding a drift button. There was one bug during that process where if you started drifting your steering controls would invert, so to fix that I added some logic that sees if the input acceleration is negative, and then sets the input acceleration to 0 if it is.
After all of that I imported the big track into a level and tested out the vehicle in a "real-world" setting, tweaking things that I didn't like.
In the future I will need to fix a bug where the acceleration doesn't hit 0 when you hit a wall, the vehicle slows down way too much when not touching the ground, and it easily rolls over when driving up steep slopes (maybe there's a way to clamp the rotation).
I continued to follow the tutorial series and added a lap counting system using a spline and a bunch of fancy nodes.
During the tutorial I chose to leave out some minimum lap decrease code (so if you drive the wrong way for five laps, your laps will decrease by five); and instead of having two widgets - one for the HUD and one for the laps - I decided to just have everything in the HUD, because I remember Curtis talk about having as few widgets as possible.
After making the finish line mechanic I realised that I was sort of doing what Troy had already done. So I mentioned this in the group chat and a after some discussion we agreed that Troy would do the UI such as the main menu or level select, and I would do the mechanics.
In the future I will continue following the tutorial and changing things where I see fit. I have also realised that the track is much too uneven, so I will need to flatten it out in the future.
I continued to follow the tutorial and added a boost pad system and a simple AI system for opponents.
The boost pad was quite simple, and the AI can sort of drive on the crude spline that I had mapped out. Often the AI vehicle will drive into a wall and not reverse, but I think that's a future tutorial. For the boost pad the tutorial even briefly covered how to make a scrolling texture.
I had also learned how to clamp things using the nodes with a little help from a YouTuber called "UE BP GURU"; I clamped the X and Y rotation to prevent the vehicle from driving up the wall and into space, making it more stable.
One issue that I had with the AI is that it would often get seizures when hitting bumps or going round sharp corners. First I debugged this by measuring the player rotation values with the Print function and measuring the AI's rotation values; as the tutorial mentioned before, I found that the rotation was way too high, so I clamped the maximum and minimum AI steering value to ["Player Rotation Speed" X 1,000,000] and [-1 X "Player Rotation Speed" X 1,000,000] which stopped the AI from over-steering and freaking out.
I also added a little code that tips the nose of the vehicle down when it is not touching the ground to prevent flight; I did this by detecting if the vehicle is touching the ground and then shifting the centre of mass to what I assume is the back, which for some reason tips the vehicle forward.
There is still the issue that the AI isn't very good and that when you hit a wall you tend to start spinning out, so in the future I will need to fix that.
I tried to make the vehicle not spin out when hitting a wall, but I couldn't get it to work; I tried collision boxes and hit events, and redirecting the vehicle to the spline, but it just didn't work.
I even started off by trying to write out the logic.
In the future I will try to use ray casts/ sideways suspension to gently push the vehicle away from the wall.
Today I spent all day making a hardly functional position/ leaderboard system.
I had visited quite a few websites, but not all of them helped.
I was following a tutorial on making the leaderboard, but the tutorial used bars of colour that switched places. I wanted my leaderboard to use numbers. After some trying I decided to make a Python script to lay out the logic. After some more time I managed to get the Python script working perfectly and started translating it into Unreal Engine's blueprints. This took me many hours, and by the end of many iterations I only managed to make it half work. When you overtake the AI, you get first place; when you drive backward, you do not lose first place. Also when you overtake the AI sometimes you get 0th place, even though there is absolutely no code that overwrites the position numbers. I have a function that is run once that assigns incremental values to the loaded vehicles; after that the spaghetti loops every 0.25 seconds and organises it in a bubble sort method. Nowhere does it ever add a zero or subtract from one.
In the future I am going to need to watch the spline position data and cry I guess. Sometimes I wish I could skip the awkward middle-man and go straight to the C++.
One place which didn't make sense was that I had to flip some comparison (>,<) logic in the position checking sections to make it kind of work, even though it worked perfectly fine in Python; maybe that change is somehow screwing up the logic.
I fixed the position system! For the most part...
As it turns out, I had the wrong "LeaderboardPos" variable plugged into the bottom set node. But during the troubleshooting I also managed to remove a redundant branch node. I also fixed the lap counting system, so now when you drive backwards through the finish line, it counts down.
But right now there is an issue where the spline data isn't accurate and can artificially inflate if you go forward and backwards a bunch. And for some reason you lose first place if you touch the finish line. The tutorial did mention some math for converting the spline data into a percentage, so I guess that was important?...
I will try to fix the spline stuff, and continue the tutorial.
To finish the day I did a little UV unwrapping to the foliage and track modifications.
Today I added some hacky code that doubles the gravity if the player flies up too high, the gravity feels a bit harsh at times and feels like the wrong solution, but it mostly stops the player from flying into the atmosphere.
I also tweaked the suspension to sit lower to the ground and be softer.
After that I set the rotation inversion code to compare the acceleration input with -0.05 rather than 0; this allows the player to rotate on the spot in the correct rotation, since no small negative numbers invert the controls.
After that I spent quite a bit of time trying to make the AI handbrake turn in sharp corners, which works perfectly at slow speeds, but the AI doesn't follow the spline but rather its rotation, so it often crashes. The AI also uses the handbrake too much, slowing itself down. Maybe I need to lerp the values so that spikes in data don't enable the handbrake?
After that I tried adding a frictionless physics material to the collision box, doing a surface level google search to learn what "Restitution" means, and then setting it to 0 with the combine mode being set to "min". This stops the vehicle from spinning out from collisions with walls, as restitution controls how bouncy the object is.
Today I improved some major game elements, and in the future I am going to need to fix the AI and allow the player to reverse immediately after hitting a wall.
Today I added left/ right movement for the mesh to add emphasis; I did this by setting the rotation relative to the steering angle, and eventually after trying multiple "Interp" nodes I managed to smooth the movement over with FInterp. I also did the same with the camera movement, but for that I am going to need to add a toggle in the future for accessibility.
I also fixed the issue with the vehicle not reversing immediately after crashing; I did this by having two line traces for the front and back where if they detect something they set the input velocity to 0, which then doesn't need to decrease from 1 in order to reverse.
Now to fix the AI.
Today I followed the tutorials for item boxes and missiles; but I got tired of unreal and left it in a non-functional state for today.
After that I finished UV mapping all of the foliage material walls.
I spent a great portion of my time today trying to fix the AI, and I could not figure out how to make it steer towards the spline instead of along with it. I am going to need to ask Curtis for help because there is hardly any information for exactly what I want to do.
I then tried to fix the item box system. I tried to look back at the tutorials to see where I went wrong, and I couldn't see anything different that would affect the spawning. So I wrote some code logic in notepad that I could in the future to write my own item system from scratch.
I then UV mapped the buildings a little as to have done something productive today.
I added a variable for completing all the laps, and I added a variable that can change the number of total laps.
Then I spent the rest of the day making spark effects for when you scrape stuff. I initially got line traces for the ground distance that would enable the visibility of the particles. Then I did the same for the sides, but by doing so the ground ones stopped working. There was something like a limit, so I tried combining everything into one function; but that still didn't work. So now I am trying to use collision boxes instead, but they hardly trigger/ stay triggered.
For the particle system I made a one-pixel texture and followed a tutorial on how to make spark particles. Then I found out how to make the colours change with time from a thread.
In the near future I am going to need to have the AI fixed, the item boxes functional, and the sparks functional.
Today I watched a collision spark tutorial which used hit events instead of collision boxes and attached particles.
It was quite simple then, but I did find that my particle effects weren't showing up; so then I googled the problem and discovered that I needed to enable a "Local Space" option in the particle settings.
Today I didn't even use Google, and I made a working item box with a working speed boost.
When a vehicle runs into an item box, the box sets the vehicle's "Current Item" variable to a random number within a range, then the box stops being collideable and makes its mesh invisible for two seconds before reappearing.
Then there is a loop that checks what item is being held and wether the player has pressed the "use item" button. There is also code to make sure that you don't use an item if something is in use. The boost item can be used whenever as long as a boost item isn't in use. There was an issue where if you pressed the "use item" button and the item didn't get used, it would wait until the item runs out and then automatically enable itself. To fix that I added some code that only allows the button to be used if the boost isn't enabled. This will 100% not work for more than one power up.
I'm going to need to replace this code with "if CurrentItemsBeingUsed != -1". Oh right, the "CurrentItemsBeingUsed" will be a list in the future; so the code will have to be: "if len(CurrentItemsBeingUsed) == 0:". Yeah, I think that just adding and removing the active items woud be best. And with the item enabling code I am probably going to have to change it to have the power ups work if they themselves are not enabled, rather than allowing other power ups to enable them; or whatever the current code does.
I did a little UV mapping of the track building material near the end of the day.
Today I UV unwrapped all of the building material.
Initially I was just scaling and straightening the UVs and then moving the sides to match up with the edges of the texture. Then I realised that it would probably be best to straighen out the diagonals so that the textures didn't seem so warped; then I realised that there is a pattern at regular intervals of where all of the edges are, so I decided to merge them; after that I realised that the edges of the texture didn't alighn with the texture borders, so I applied a known symetrical texture and set all of the UV vertices to points of 0.5.
I have also decided tha maybe it would be easier to reuse textures for potential future models if I don't combine them together for performance, so I decided to separate the metal wall texture from the guard rail texture and UV the metal walls.
After that I then added some dead ends with their own material.
In the future I am going to need to UV the roads, fences, and guard rails; and help out with the textures by making the chain-link fence and possibly creating a building template/ example to help make better materials.
Today I added the slowdown power-up that slows opponents down in an area.
I added a collision sphere that slows down kart actors when they enter the collision. An issue that occurred was that the collision sphere would pick up all of the item boxes, so I added code that would make the item boxes disappear only if they collide with the body of the kart.
I also took some of John's 3D models and made them work with Unreal Engine. I took the bin texture, added wheels, and rendered it to then put in Unreal Engine as a billboard; I then realised that it is bright green and may cause distractions which isn't very accessibility friendly, so I made it darker and added an emissive brick texture for a sci-fi look. The item box had a similar process; when I put the texture into Unreal Engine I realised that it will blend in with the environment, so I added some bright pink CRT-esque lines using the wave texture to create contrast. I also updated my "tree wall" texture to seem less repetitive by moving the trunk further back, and making the bottom leaves slightly less vibrant.
In the future I really need to fix the AI because not even Kurtis knows what to do.
I watched a tutorial on how to make an AI steer along a spline.
I managed to make the vehicle follow the spline, but it follows it really slowly and wobblily.
Will gave me feedback to make the vehicle tilt when you accelerate and decelerate; turns out I already had the code implemented, so I just increased the values from -5 to -10.
I feel that I am closer to a functional opponent, but I need to tweak it to move faster in the future.
Today I made four textures; two trees, a fence, and a guard-rail.
I made the trees by using geometry nodes and cylinders. It was really difficult to get the foliage right, because trees droop and their leaves are held in clusters. For the first tree I found that bigger leaves makes the tree look more natural at a 64 pixel resolution. With the pine I was trying similar processes to the first tree, but mimicking pine needles is harder to do with geometry nodes than a fluffy tree. Eventually I made the leaves point more down (needles didn't give piney results). For the pine tree's leaves to point more down, I needed to use three "Random Value" nodes and a "Combine XYZ" node.
The trees look fairly nice and people probably won't notice as they speed past. The trees are better in the realism scale than Mario 64's; so I'll count that as a win. But the pine tree is too fluffy in my opinion.
I also made textures for a chain-link fence and a guard-rail.
For the chain-link fence I tried to use a curve, and cutting out a cube; but I couldn't figure out how to make everything flow and overlap like a fence. So I turned to Google and found a five minute tutorial on how to make a fence using bridge-loops and array modifiers. Then I made a physical version with the modifiers applied, set it to the centre, merged some overlapping vertices together, aligned the edges with the edges of the camera for tessellation, and tried different scales for the right transparent-to-opaque ratio.
For the guard-rail I modified a plane, added a modified cube for the support, and added some bolts with modified cylinders. I added some metallic materials with noise textures for a brushed effect, and an emissive strip to make it look more science-fictioney. For the render I used a slightly angled sun light, and placed some planes with an asphalt-like material to bounce the light evenly over the model. I set the planes to be hidden to the camera. After that I rendered the image and put it into GIMP to opaque-ify some unnecessary translucent anti-aliasing pixels; but I did leave some to make the holes look rounder, I checked "BeetleAdventureRacing" and found that the "puddle" ground uses gradual transparency rather than binary, which means that the N64 supported it.
I then added the new textures into the materials of the track and UV unwrapped them like with the buildings except the guard-rail was aligned with the scale of 1, and the fence wasn't aligned on the X axis.
I also reworked John's building a little to centre it with the camera better and swap the colours to a shade of blue using the colour ramp.
Today I decided to create a second building model.
It is essentially a subdivided, inset cube with an empty interior containing one floor that has an emissive texture on the back wall. The door was just another subdivided, inset, extruded cube; technically two cubes that came from one. I also created more brushed metal materials with noise and displacement maps. One issue I faced was that the metal wall material looked really flat, so I added a subtle wave texture to make a lighter section in the middle and a darker section on the top and bottom. It is much more simple than John's model, but I think it still works; hopefully my art style won't clash in the game.
I also did a bit of work on making a road material. Basically just squares and brick materials; at least so far. I often refer to the sci-fi mood board to get the feel for what something should look like.
Tomorrow I will either continue with the roads, or try to fix the AI; but I kind of want to do something more visually creeative.
Today I created all of the road textures, rendered everything in night lighting, and UV unwrapped all of the roads.
When making the roads I just continued making cubes; quite simple. The I combined all of the seperate textures into on long one. When rendering everything to look like it is night time, I just rendered everything with less light. When I finished rendering the roads I marked that task as done in Trello.
When UV unwrapping the roads, I used a similar method to the buildings, but vertical. And I aligned all of the UV edges with the seperate images in the texture. While UV unwrapping, I had google maps open with Canterbury in order to see what types of roads are where.
In the future I am going to need to render some dead-end textures, make a skybox with a sky material, add fluffy foliage planes for the tops of the foliage walls, and render a fluffy foliage material. An then I'll count the big level ready for cut-up and export.
Today I spent time working on the signs that block exits.
First I imported the current level into Unreal Engine and applied the materials. I didn't like how different faces had different shading from the directional light, so I set the light to 0 and added emission to all of the materials in order to see them; that seems like a janky way of doing things, I may need to consult Curtis.
John sent me what he had modelled for the sign, and I added a few pipes to it using curves and a "Curve to Tube" modifier. Then I cleaned up the animation and added an invisible cube for a boolean modifier in order to cut off the arrows on the edges; one issue that I encountered was that the animation would briefely stop at the end of the loop, but eventually I realised that I need to move a keyframe forward by one because I essentially had two identical frames at the start and end. After that I rendered the animation into 20 frames. Then I tried to bake the complex mesh into a diffuse texture, but it turns out that it only works with normals, so I rendered each significant side and spliced it together in GIMP; it is incredibly janky, but luckily it is low resolution, so it is not as noticeable and looks quite good. I tried to add the road barrier to Unreal Engine, but UE doesn't support GIFs and also doesn't support it's own image sequence and media player; it's bugged and I'm going to need to fix it.
Today I fixed the sign animation.
The media player kept removing and not seeing media sources, and I just couldn't get it to play anything. Then Will told me to make a scrolling texture instead of an image sequence; I ignored that advice. I kept persevering and trying to find a fix for the issue. I then discovered that if I save a playlist and use that to reference the image sequence, the texture/ material then plays in the viewport; but the moment you play the level the media player would remove the reference and become blind to all of the sources again. So I kept looking for answers, until 100 tabs later I discover that I need to use blueprints to open the source and set the image sequence as a reference. When you play the level, the material plays with all the correct fake lighting.
Tomorrow I may try to fix the AI acceleration, add tree fluff to the tracks, and maybe render the street light.
Today I rendered the street light, created the tree fluff, and UV unwrapped/ moddeled all of the tree fluff into the track.
For the street light I downloaded the file from John, angled the camera how I want, added a light sphere, added a plane of glass material to catch the emission material's light, and added a box around that plane to stop the sphere light from bleaching the glass into a solid white. After I rendered the image, I placed it into GIMP and gave it a proper alpha by pipetting the colour and drawing each pixel of the post as a solid, and then making the light translucent and not black. When I first exported the image, I discovered that it had a lot of bright blue pixels in places that it shouldn't; so I added a black background for visibility to my project and made those pixels much more translucent.
Then I made a tree fluff texture with geometry nodes, like I did with the tree wall texture.
And then I started adding the fluff parts to the tree wall parts of the track. I did this by hiding every material that wasn't the tree wall, selecting all of the top edges of the tree wall sections, extruding them up three metres, cutting them out of the main mesh with "P"-"Selection", and then spending the rest of the day UV unwrapping and angling those new sections. At some point I also took some reference to see how fluffy the shrubbery of "Beetle Adventure Racing" is, after which I did some tweaks to the texture.
I really need to get back into coding the mechanics and fixing the AI.
Today I made a skybox, a dead-end texture, and started unwrapping the dead-ends.
For the skybox I cut an icosphere in half and applied a sky+voronol+noise texture to the material; and then baking the material to the texture.
For the dead-ends I rendered 4 different straights with a turn in them to give a crude illusion that there's more road; then I stitched the four textures together in GIMP.
Then I unwrapped the dead-ends basically the same way that I UVd the roads.
In the future, maybe tomorrow, I will try to fix the AI.
Today I followed the AI steering tutorial to make the AI kart accelerate properly, I managed to make the AI actually competent and be an actual opponent; it was able to regularly, and reliably, complete a lap. I had also discovered that putting a sharp kink into the spline can force the AI to use the handbrake.
I also slightly optimised some code by removing a loop, and only allowing the camera clamp code to run if it is the player.
Then I closed Unreal Engine and committed a change to Diversion which caused a bit of corruption. I wasn't able to open anything from the content browser, but eventually I discovered a post and managed to open a blueprint by maximising the blueprint window through Tassk Manager. But something didn't feel right, the leaderboard started flickering at the start, and the AI started clipping through a wall. So then I tried reverting the changes by "Cherry-picking to workspace", then my leaderboard wouldn't compile. I asked for help on the Help channel in the university Discord, and I was told to replace the "For Each" loops; I discovered an extra loop to replace, and was then back to the slightly off compileable place. The leaderboard and AI still act differently than what I remember, and I don't know what to do about it.
Today I decided to 3D model some assets; a bullet, a bridge decoration, and a non-opponent vehicle model. If the concept artists don't do anything, then we'll have a backup vehicle model.
For the bullet I just got a three-faced cone, and applied a gradient to it (found a Reddit post that made me take the simpler gradient approach that is not tied to the scene Z coordinate).
For the bridge I got a cube, scaled it, removed most of its faces, UV unwrapped it, exported the UV unwrap edges, imported the UV texture as a reference, added a bridge shape, added piping and access panels (for the bent pipes I used the bridge tool). For the lighting I separated the faces with planes to allow a different light level for the underside, and added a cube-turned-to-sphere to use it as a light with two different light materials applied to it.
For the vehicle I took the same concept. This vehicle was heavily inspired by the Volkswagen Beetle because we needed round civilian vehicles. So I took the rough dimensions of the Beetle and started modelling the vehicle 3D model. Some loop-cuts and simple 3D modelling later I finish the model, marked edges for cutting, and UV unwrapped it as Conformal. Then I took the UV edges, modified a plane to all of the edges, made the plane three-dimensional, and started adding all of the details. After I was finished I rendered and tweaked the model.
This process doesn't work flawlessly, but it is pretty good. The much more efficient and reliable way would be to make the 3D model in high detail, export it to Substance Painter, and bake the colour to a lower poly model. But screw Adobe. Hopefully Blender adds the functionality in the future.
I marked off the tasks on Trello, and in the future I am going to need to finish the tracks; I am so close, I just need to finish it up.
Today I started by making an industrial building texture, and rendering all of the buildings with a top half, for the higher walls. I used the curve tool for the pipes, and a wave texture through a colour ramp into a displacement for a garage door material. When I rendered all of the textures, I stitched them vertically together in GIMP.
Then I finished UV unwrapping all of the dead-ends, re UV unwrapped the walls by moving the vertices down to n÷6. Then I selected the faces that I wanted to change and moved them up by 0.333 or 0.666.
Then I started cutting out the first level's mesh, removing any faces that wouldn't be seen by the player; looking down the roads to check.
After that I duplicated the mesh, removed the materials, and changed the mesh to act as the collision. Then I added a roof to the road collisions and used it as a Boolean that I inset into a cube; then I crudely retopologised the cube. The cube should hopefully stop players from accidentally clipping through.
In the future I can start building the first official level. But I also need a sci-fi warehouse and cathedral asset.
Today I decided to start making an official level.
First I imported the level asset into Unreal Engine, and applied the collision asset as the collision (which still allows you to clip through). Then I decided to find a better way of having flat shading than having everything emissive; In a forum I discovered post processing volumes and ambient cubemaps. But then I discovered that the particles still don't show, and that making the material emissive just made them white. But then I found that I just needed to drag a line from the multiply node.
Then I started laying out the spline in a similar way to before, but I quickly noticed that with more than one opponent the leaderboard stops working. After a lot of trial and error I discovered that the player is not index 0, but the last one spawned in (so in this case index 5 (len(vehicleList) - 1)). That made the swap logic work, but you started in 1st and made your way up to 6th; so I swapped two inputs in a comparison (>) node.
Now I've noticed that the AI don't know how to overtake so they just pile up in the corners. In the future I may need to rework the AI as a child of the player class, and make them swap splines when they come close to each other. If none of that works, I could just give them a wedge collision.
First I added a countdown to the UI that holds everyone still until it finishes. I did that through a series of delays when the HUD initialises.
Then I tweaked the spline for better veehicle speed and added assets. I found that the opponents are a bit of a challenge on their own, but are really easy to overtake when they pile up; so I spaced them out, and it sort of works. I should probably add collision avoidance, but this works for now.
Then I quickly went into Blender, tweaked the visual mesh to have an extra face, and modified the collision to be a hollow tube that might work if I'm lucky.
Today I made a bunch of assets and their materials for the game.
I started with the warehouse; very similar to the bridge process, but this time I used area lights.
Then I got up the Canterbury cathedral on Google Earth, created a model of it, painted some vague details onto it for reference, imported that image into Blender as a refence image and used it to position all of the details. The windows were punched in by using the Boolean modifier.
Then I made the opponent's vehicle which is based on the BMW M3. The process went similarly to the civillian vehicle, but this time quicker since there's no round shapes.
I think the models turned out fairly well, though the vehicle seems to lack detail; but my reasoning behind that is that the real-life BMW didn't have any contrasting traims, and instead got it's detail from the shape of the body.
In the future I will need to make the player vehicle, and develop the game to a functional level.
Today I mainly added assets to the Level 1 map and set the vehicle's mesh to the BMW.
I also started making a death box since Unreal Engine can't handle collisions. It doesn't send the player to the spline right now, and doesn't really work.
In the future I will need to fix the death box, make the AI seperate from the player blueprint to allow for easier changes, and just work on the game so that it can start and end.
Today I tried to fix collisions and gave up. You appear to clip through if you drift into a wall sideways with speed. I don't know how to make the collisions work.
I then asked Curtis about delta time, and learned about "Get World Delta Seconds". I then multiplied it into the drift deceleration code and tweaked it until I was happy with the speed at which you can travel around corners. Unfortunately the spline no longer works for the AI, and I will need to tweak it again.
In the future I will need to link the UI with the game, and make the Z death code send you to the location of the spline. How do I fix the collision?
Today I started by discovering "Continuous Collision Detection" (CCD) while Googling my wall phasing issue. That box kind of helps, but you can still clip through.
Then I added the ability to look backwards when pressing "Z" on keyboard or "⬇" on a controller.
Then I found the spark video in my bibliography and started adding sounds to the game. I need to make a metal grinding sound, but the sounds do play when you scrape the walls. I also made an engine sound from an oscillator audio website by combining a 100Hz wave and a 1Hz wave; then I took a screen recording, converted it to MP3, cut it up, and compressed it into something more similar to what the N64 was capable of. Unfortunately the engine sounds don't work that well; all of the vehicles run the engine sounds in sync at the moment, and the pitch doesn't change the speed of the audio. I'm going to need to learn how to dynamically change audio speed, and apply it to either the throttle input or the vehicle speed.
In the future I am going to need to make everything sound good, find or make music, potentially make more assets, figure out how the main menu UI is doing, potentially make assets for the UI, make sure that the level is playable from the main menu, figure out how to save data, add more levels.
Yeah, three weeks is plenty of time.
Today I rendered the starting race countdown, and made the body of the vehicle rotate on the Z axis a little when drifting to enhance the feeling a little.
This does mean that the body of the vehicle may clip through things, but it shouldn't be too noticeable. And I want to re-render the countdown without the glitches, because gritch lines move, and these ones don't.
Tomorrow I might work on the AI overtaking mechanics.
RToday I started by giving the AI a bit of an overtaking ability. When they sense a BP_Kart actor in front of them, their rotations are clamped to a lower value of 0.35 which forces them to steer. If I knew how to use the spline better, then I would have moved the vehicle's target position to a virtual offset of the spline; but I don't even know how to respawn the player at the spline, so the AI just run into each other at an angle and spin out. This does make the racing line more wobbly and adds interest to the game, but the laps are not consistent. Sometimes you overtake everyone, and then get overtaken by half of the opponent behind you; and sometimes you finish in last. The AI tend to pile up in the corners even more than they used to, but it is still basically impossible to win; I need to balance that out.
After that I created a blueprint with a large sphere collision box that sticks to the player's location. This sphere controls wether actors are visible or not. I did this to mimic Mario Kart 64, where enemies and opponents pop out of existence if they are too far away.
Then I did some learning about Meta Sounds and how to edit variables and whatnot. I managed to get the engine sound to play, with the audio speed linked to the movement of the vehicle. Unfortunately the sounds randomly cut out for no reason after a while; and I don't think it's got anything to do with constituency.
In the future I am going to need to fix that audio cut-out, make the lamp posts a blueprint in order to have them pop in and out as well, remove the glitches from the countdown renders, and a bunch of other things.
First I started by creating position number renders. I took some blender text objects and traced them with cubes. Then I inset them, added materials, and rendered them.
Then I added some logic that compares the leaderboard position and then sets the UI image to the correct number.
Then I added difficulty logic and tweaked the values to something that I felt was fair; hopefully the AI will work the same in the stand-alone game. I found that the differences between the difficulties are large enough that they are noticeable, but minor enough to not need multiple splines.
I then rendered a box for the laps to be put in. I think that it is better than the placeholder, but it is maybe a little strange compared to the position counter.
I also re-rendered the countdown in a higher resolution because it looked like a scaled up JPG from Google.
In the future I need to create main menu assets, get a hold of John's assets, fix the audio, and hopefully add more levels.
Today I 3D modelled a controller in order to annotate the buttons and inform players of the controls. I used reference images in Blender to trace a cube into the correct shape, added buttons and triggers by using cylinders and cubes, coloured the controller with the colours of an N64 controller, and then rendered it with spindles. I made the triggers larger in order for them to not be hidden by the bumpers.
I am happy with the controller; I think it looks cool. In the future I need to make the UI stuff, and obtain John's assets, among other things.
Today I created a bunch of sounds for collision, scraping, handbraking, and player engine. I used the same tools that I used last time and took some sounds from Pixabay.
I then integrated those sounds into the blueprints. One issue that I had is that exporting sounds always created a popping noise at the start/ end. Then I discovered that it can be removed by setting the start and end position after and before the popping.
The audio still needs fixing; it still cuts out when leaving the attenuation area, and it kind of hurts my ears.
Today I created a roundabout asset, modified it's collision to not throw players in the air but me a noticeable bump, and added trees to mimic the roundabouts of real life.
Then I rendered John's start line and added it to the start blueprint, and added code to flip it through the colours of the traffic light. Later my friend Harry suggested that I add the checkers like in every other racing game in existence, so I quickly made an asset and added it to the blueprint.
I also tried building the game, but initially it didn't work. I asked Will and he reminded me that people fixed it by disabling the Diversion plugin.
I really need to make finish lap UI, I should just do it.
Today I started off by asking for help on the Discord help channel to fix animations not packaging and audio stopping when leaving the attenuation area.
To fix the packaging I needed to create a "Movies" folder in Unreal Engine and put all of the animation stuff in it. Apparently the working animation may work on my computer, but might not on others; so I sent the build to my team to test. They didn't reply. To fix the audio I needed to go into the MetaSound file and delete the "UE.Source.OneShot" interface.
Then I created a bunch of posters to decorate and reference Canterbury. For the posters I created a system where I could change a variable's number, and it would change it's material/ visibility/ mesh once the game loads.
I also improved the AI steering when they get the boost from the boost pad. I did this by increasing how far forward they can see, which allows them to react faster.
In the future I need to make the finish line interface, and hopefully I'll get the vehicle concept art too. And hopefully Troy is managing with the main menu.
Today I started off by creating a "Sensitivity" variable that controls how much the player turns; I did this by just multiplying the math by the variable.
After that I modified John's boost pad model, rendered the animation, created a mesh, imported the stuff into Unreal Engine, and added it to the boost pad blueprint.
I also added taillight trails for when you boost. I tried to finterp the world rotation of the taillights with the world rotation of the body, but Unreal Engine didn't allow it to work properly despite the very simple task.
Then I created a simple finish line UI with your place and a button to restart (which works) and a button to quit to the main menu (which isn't functional yet); the UI pops up when you finish a race. I might ask Troy to hook everything up properly since he has more experience with UI by this point. The mouse isn't visible and the UI doesn't support controller, so that will need to be taken care of.
Then I fiddled around with some nodes to make the player vehicle into an AI when you finish the race, and I made the camera look back indefinitely to show the front of the vehicle.
After that I watched a short tutorial on how to make a "blob shadow" using decals.
Then I finished by adding variables for "EngineVolume" and "EffectVolume".
I want to start making more levels, but I'm worried that Troy may need some help. I also need to make a video showcasing the game at some point as well. Maybe find some royalty-free rock music as well. But the game looks good, and the list of necessary tasks seem to have shrunk to a manageable quantity.
Today I added level 2, complete with spline and posters.
I added two boost pads on some of the longer roads, but I noticed that it makes the AI unbeatable; so I made the spline suboptimal, making them take the corners wider.
I still need to make the player vehicle, but I am yet to recieve the concept art. I might make another level. I might need to learn how to save things, if Troy hasn't worked on that yet. I also realised that the "Retry" button (Wait, is it retry or restart?) will always take you to level 1, so I might need to fix that. And I will need to make a video as well.
Today I made the player vehicle 3D model from John's concept art. It was quite a complex shape and had a lot of difficult details, but I managed to make it fairly similar in the N64 style. This really put my current skills in perspective, because although I am able to make 3D models fairly easily, I found that I struggle to recreate shapes from a source.
After making the vehicle and texture, I then put all of the assets together and made a main menu background. To make the headlights emissive and not the body, I put the texture through a colour ramp that I could adjust, and then plugged that in to the emissive output. After placing objects, lights, tweaking materials, and adding geometry nodes that I took from my texture creating project; I rendered the scene at 480p to emulate N64 resolution.
Then I put these assets into Unreal Engine, making the player vehicle spawn with the vehicle mesh, and having the textures in the textures folder. I tried to fix the widget by having the level set the retry button's level-to-load, but when I tried it, it still sent me to level 1; I even tested to see if the variable is "Level 2" when it loads, and it is, so the issue is not with my code.
In the future I am going to have to make a video for the itch.io page.
Today I started by fixing the "Retry" button. I did this through lot's of trial and error, but eventually I managed to set a name variable right as the widget is being created; and that variable holds the current level's name. Setting a world variable in a not-yet-created UI from the level blueprint didn't work.
Then I added a "FieldOfView" variable to change the FOV; as the brief insisted we do. Then I realised that I could change the FOV when the player boosts; so I spent quite a bit of time trying to make the system FInterp properly.
Also, I finally switched the "Look Back" button from "Z" to "C".
All that I need to do now is make sure that Troy is managing the UI, add a camera switching system, record and edit a promotional video, and hope for the best.
The first thing that I did today was create a mechanic where if you press [Tab], the camera switches. The purpose of this was to allow me to get multiple cinematic angles of the vehicle for a trailer/ video that we have to make.
Then I opened OBS and recorded three laps for each camera angle.
After that I opened the Blender video editor, added all of the videos in, cut out the unuseable bits, and started stitching something together. So far the video looks awkwardly stitched; hopefully something good comes out of my efforts.
I am going to need to finish the video and Itch.io page by Tuesday. And I really hope that Troy manages to meet the deadline with something workeable.
Over the weekend I had managed to stitch together a collage of clips.
Today I added the royalty-free music by Flowerhead, and added a bit of animated text. I don't know how to make videos well, I don't have experience, so it looks okay-ish. But that is as good as I can do.
I then created a version of the main menu but with the title. GIMP unfortunately doesn't have the option to put outlines on text, so I usually just layer two different sized texts on top of each other as a lazy way to add an edge.
After that I uploaded the video to YouTube to then add to the Itch.io page.
I also fixed a bug with the leaderboard where you would get first place no matter what when you crossed the finish line. It turns out I just needed to move the beginning of the spline before the finish line, but after the first opponent.
Then Troy sent me his files. His main menu barely had anything; you could only load one level, there was no accessibility...
So I added the ability to load Level 2, Accessibility settings, Ability to save accessibility settings, A very quick and crude Windows 95 icon, Improved the pause menu. I've been working since about 11:00am; it's now almost 02:00am. I'm uploading the project onto Itch.io through my phone's hotspot. I'm almost finished.