<![CDATA[dev - ruby0x1.notes]]>https://notes.underscorediscovery.com/Ghost 0.11Thu, 04 Feb 2021 04:06:10 GMT60<![CDATA[UE4 - list blueprint assets by type]]>I'm busy working on a project in unreal lately, and ran into the desire to enumerate a list of blueprint assets from a folder. This post has a simple solution.


I looked around and found this post which covers finding UClass from a type, native or from assets, but didn't

]]>
https://notes.underscorediscovery.com/ue4-list-blueprint-assets-by-type/07696f7c-4ec8-4117-bde8-2db45b0baa69Tue, 27 Mar 2018 13:22:25 GMT

I'm busy working on a project in unreal lately, and ran into the desire to enumerate a list of blueprint assets from a folder. This post has a simple solution.


I looked around and found this post which covers finding UClass from a type, native or from assets, but didn't feel right for my needs. I then found out about UObjectLibrary and after figuring out some of it's API, found this post which also helped. UObjectLibrary been working well and has lots of neat little helpers in the API for what I wanted, and the code is simple.

The code is at the end of the post.

important notes

Make sure the path you use exists in the cooked data in packaged builds. The project has settings for forcing folders to be cooked, add them there if your code is assuming they exist.

All Content/<folder> paths are referenced as /Game/<folder> when using this. Here we have /Game/Trees and /Game/Cards.

UE4 - list blueprint assets by type


The point

Let's say I was doing some procedural generation, and I wanted to spawn some trees (or even whole chunks of a level). These trees can be made into blueprint actors, and spawned dynamically. But how do I get a list of them to spawn from in the first place? That's what we want here, and this is what we'll get.

UE4 - list blueprint assets by type

Type filtering
You'll notice that Type Class filter, this is useful to be specific about the sub class, so that you can cast knowing each result is of the right type.

For example, in my case I have a c++ class called EventCard that all my "card" blueprints inherit from, then I can select it here. Then, I can cast to the specific class and use it as that type, if I wanted to. (This also means you can mix types in the same path/folder, and query only ones that you want).

Spawning
This example also shows how you can take the type and spawn an actor from it. Since the class is just a type of tree, we are now creating one actual tree from it. We can do that several times for the same class, making many from one.

UE4 - list blueprint assets by type

C++ spawning/usage
This code example assumes all my blueprints are inheriting from the c++ class AEventCard, which they are. (see unreal wiki for GetWorld() alternative)

TArray<UClass*> list;  
helper::GetBlueprintsOf(AEventCard::StaticClass(), TEXT("/Game/Trees"), list);  
UClass* cardClass = list[0]; //assume it found one, use the first one  
AEventCard* card = GetWorld()->SpawnActor<AEventCard>(cardClass);  

Code setup

In my case I had two goals:

  • I want to use this from c++
  • And I want to use to use it from blueprints

The general idea is we want one c++ function, and then one blueprint-facing wrapper function to expose that. The Unreal Wiki has some great examples of exposing stuff to blueprints so I won't get too specific, but I will provide hopefully a clear example of how it'll be setup.

I already have a general purpose blueprint function library in c++, called "TypesAndGlobals", this is where I'll expose it. If you don't have one (and want to use this and don't mind c++ in your project) you would create one from File -> New C++ class and choose Blueprint Function Library as the parent class.

Once the function is exposed then we get this:

UE4 - list blueprint assets by type

The code

]]>
<![CDATA[PROJECT CEDAR DEV#3]]>Continued, A short dev post about a tiny stealth game in http://pico-8.com.

For something I'm just slowly making for fun on the side of my side-side projects it has been fun to isolate scope so heavily. Here's a short update of how it's going.


Last weekend I tweeted

]]>
https://notes.underscorediscovery.com/project-cedar-3/ed647e48-0828-4931-ab6c-2ef292a23bebSat, 12 Mar 2016 07:41:32 GMT

Continued, A short dev post about a tiny stealth game in http://pico-8.com.

For something I'm just slowly making for fun on the side of my side-side projects it has been fun to isolate scope so heavily. Here's a short update of how it's going.

PROJECT CEDAR DEV#3


Last weekend I tweeted a new gif of the intro area in the game. I was tweeting on a Saturday night, not expecting much but a whole lot of people were sharing and showing interest. I was grateful!


Previously I mentioned the code limit updates in pico-8 and sticking to the original 32k limit for my own constraints... So far I haven't been too far over and I've made significant progress on the game as a whole. Lately I've also been coding a lot more freely instead of carefully, so I might even still make it by the time I'm done - The important factor is I don't need to sacrifice the game itself on the limits so I won't do that if it comes to it.

PROJECT CEDAR DEV#3

What is PROJECT CEDAR?

One thing I was trying to nail down was this. Not like, what type of game but what is it to me and what is it I want from it ultimately, aside from just the basic concepts.

I've been in a weird transitiony headspace for a long time (like, yeaaars). The end of 2015 and leading into 2016 I was starting to figure it out, and now I finally have.

While this game is a love letter to games that occupied my mind growing up, it's part of something so much bigger to me – I can't wait to release it.

Actual progress

I've finished all the core mechanics and gameplay, as far as code goes that isn't level/story specific it's feature complete. I've also finalized the first couple of levels as a whole, and I've also polished and finished more of the story stuff. The first full play through is prettty close to playable. Since there are a couple to do it's not done but getting there.

Since I showed a bit of this area before,
here's a close to final version for comparison.

PROJECT CEDAR DEV#3

]]>
<![CDATA[PROJECT CEDAR DEV#2]]>Continued, A short dev post about a tiny stealth game in http://pico-8.com.

I had a short break from working on this, while waiting for pico-8 0.1.4. In the meantime I had finished blocking in all the details of the narrative and how that all ties together.

]]>
https://notes.underscorediscovery.com/project-cedar-2/0d0dc83f-d0d0-40c0-8790-8d351b5b3a89Tue, 12 Jan 2016 11:56:15 GMT

Continued, A short dev post about a tiny stealth game in http://pico-8.com.

I had a short break from working on this, while waiting for pico-8 0.1.4. In the meantime I had finished blocking in all the details of the narrative and how that all ties together. I planned a lot of levels on paper and graphed out some ideas for overall structure, and I've done a lot of other stuff that would spoil things if I posted about them at the moment.

Here's a less spoilery, vague, outdated graph diagram before I talk a bit about what I've been doing here.

PROJECT CEDAR DEV#2


The new version of pico-8 fixed some important issues regarding the character limitations (not that they exist or are low, but rather that there was memory corruption when you reached the boundaries. I spent around 99% of the time at the boundary for this game :p).

PROJECT CEDAR DEV#2

The new limit is 64k, with better token counting, which gives me a lot more space to work in with the code, technically. I might be able to bring back some screens or mechanics I removed for code space reasons but I'm not doing going to do that until the rest of the game is closer to done. What I am going to do is still work under the original 32k limit - but allow myself to code above the limit during active coding. Previously, I would just copy paste a section of the code I'm not working on out of the cart, then reduce the code size, and then bring it back in. This just eases workflow, which is great. There can also be less of this type of code while developing:

PROJECT CEDAR DEV#2

Aside from some minor wishlist things I was going to try and squeeze in I was pretty close to code complete anyway, so I want to limit the amount of adding I do until I really have to, and then spend the rest of the code on polish after that.

I'm currently trying to flesh out the levels needed for the narrative and gameplay. I'm debating whether I should go in order of progression, or try out "important" bigger ones with the purposes of making sure I can fit the key points in and then work backwards.

I haven't decided, so here is a wide-view teaser of a random level I'm currently working on, without any game context (so no real spoilers). Hopefully soon I'll have finished up the main levels and gotten some music in there (more on the music specifically in the next post).

(The filename says lvl-3, it's just the third image in that folder).

PROJECT CEDAR DEV#2

]]>
<![CDATA[PROJECT CEDAR DEV#1]]>As mentioned, I am making a small stealth game in http://pico-8.com.

I've made quite a bit of progress today so here is a short gif. I now have all the systems in place, and can move on to finishing out the levels and narrative, and higher level ideas.

]]>
https://notes.underscorediscovery.com/project-cedar-1/b090f2b2-4af0-4fde-b83f-a52e0ffc746cTue, 13 Oct 2015 01:18:06 GMT

As mentioned, I am making a small stealth game in http://pico-8.com.

I've made quite a bit of progress today so here is a short gif. I now have all the systems in place, and can move on to finishing out the levels and narrative, and higher level ideas. Read more below for the gif and more info.

PROJECT CEDAR DEV#1


Follow my twitter or this blog (and soon I'll have a mailing list) for updates.
 

 
Here's the title screen again for bonus points.

PROJECT CEDAR DEV#1


.

]]>
<![CDATA[PROJECT CEDAR]]>Making a small stealth game in http://pico-8.com.

You should check out pico-8, it's really great.

projectcedar


.

]]>
https://notes.underscorediscovery.com/project-cedar/1893bf1c-817a-4739-9f69-c59b11214208Sat, 08 Aug 2015 22:29:18 GMTMaking a small stealth game in http://pico-8.com.

You should check out pico-8, it's really great.

projectcedar


.

]]>
<![CDATA[Understanding Realtime Multiplayer]]>An article I wrote about understanding realtime multiplayer. Includes theory, plenty of links and diagrams and includes a working demo on github written in HTML5 with client and server for 1 vs 1 realtime multiplayer.


http://buildnewgames.com/real-time-multiplayer/

demo

Enjoy!

]]>
https://notes.underscorediscovery.com/understanding-realtime-multiplayer/2b7fc2cd-b7b3-47bd-8f52-4a03f0bb1a37Wed, 08 Jan 2014 01:45:05 GMTAn article I wrote about understanding realtime multiplayer. Includes theory, plenty of links and diagrams and includes a working demo on github written in HTML5 with client and server for 1 vs 1 realtime multiplayer.


http://buildnewgames.com/real-time-multiplayer/

demo

Enjoy!

]]>
<![CDATA[L-systems and procedural generation]]>L-systems are a generation system that uses a simple descriptor to define fractal patterns that can be useful for many things, like trees, streets and more. This post goes over the way they look and how they work.


Axioms

If you have never seen or heard of L-Systems, it is

]]>
https://notes.underscorediscovery.com/l-systems-and-procedural-generation/21890d88-a0c3-42ec-89f5-efd5d516ee48Wed, 08 Jan 2014 01:35:50 GMTL-systems are a generation system that uses a simple descriptor to define fractal patterns that can be useful for many things, like trees, streets and more. This post goes over the way they look and how they work.


Axioms

If you have never seen or heard of L-Systems, it is a fractal generator that can take a number of axioms and generate output in a fractal approach. It can almost be described as a simple language, that describes what happens to some lines as they spread out. Let's see how this works, here is an example axiom set :

Instructions (axiom)
+A-B

A set of items
A = FFFF[--AE]F[+++AE]FFF
B = FFFF

This looks a bit like variables in programming, A and B contain values, and they are replaced in the generation step by their contents.

We start at a single point and "step" outward, following the instructions in the axiom above.

Here is the output, which I will explain below.

+FFFF[--FFFF[--AE]F[+++AE]FFF[---F][--FF][-FFF][+++F][++FF][+FFF]FFF]F[+++FFFF[--AE]F[+++AE]FFF[---F][--FF][-FFF][+++F][++FF][+FFF]FFF]FFF-FFFF

We have control over the angle the step lines will happen, and the number of times to run over the step. Remember this is fractal, so things repeat on themselves. We have a small set of rules which determine what happens, at each step. For example, a - step, means that the angle at which we draw the line changes. It's like a small language saying "add the direction, then move and draw, then move and draw, then create a leaf, then move and draw".

The point of an l-system generator is to generate a final 'instruction list' at the end of the generator, which we can loop over and use, for drawing or other structures.

Instructions?

The little 'language' the above is using is relatively simple, for example, a - means that the direction the line is moving at should be changed ( -angle ), and + means the direction will add the angle we specify in the system ( +angle ).

A lowercase letter (between a and z) will move the line point but will not draw, leaving gaps in the system.

An uppercase letter will move the line point, and draw the line.

A ' will change the color you are drawing with.

A [ will create a “root node” that can have children, and a ] terminates the current root node. In other words, the [] makes a tree branch that can have its own children.

l-systems 1

What does it look like?

Remember now, that this is a fractal system, and can iterate recursively (making smaller leaves on branches, and even smaller ones under that) all using the same system. This gives the system the following parameters : 

axiom : +A-B
angle : 10
iterations : 2
linelength : 16 (pixels) 

This generates the following : 

l-system 2

Next, I simply changed the angle to 30 : 

And then 60 : 

What did I do with this?

Long ago, I was working on a small 2D game with a city component. I wanted the city streets to be generated dynamically so that the city will be somewhat interesting and unique. Take a look at the outputs when you set the angle to 90, and what do you see? Looks like streets to me!

Conclusion

The nice thing about the system is that you have complete control over the patterns (using the simple axioms), and can even generate those procedurally.
This in turn seeds the city streets, and in fact, the rest of the city.

Below are some examples with the parameters changed, all using the same axiom. The grid size changes, maybe generating blocks/business districts can be used with a larger step in the grids,        

Or maybe it can be used to determine density in population,

But for now, it is just a simple street system,

Results

The outcome is used as streets, along these lines :

Here are some resources I used to get here :

Sol Graphics Tutorials on L-Systems
In browser canvas generator with parameters
An amazing city generated with similar systems (subversion/introversion)

]]>
<![CDATA[Pathing excursions]]>I enjoy messing with path finding algorithms and finding interesting ways to obtain the results, this is about a few more recent attempts.


Paths and "I hate grids"

This post covers approaches I have been messing with to confront some of the issues I have with path finding on grids,

]]>
https://notes.underscorediscovery.com/pathing-excursions/1223694f-e1ec-415d-b15b-1aca84f2638cTue, 07 Jan 2014 23:57:04 GMTI enjoy messing with path finding algorithms and finding interesting ways to obtain the results, this is about a few more recent attempts.


Paths and "I hate grids"

This post covers approaches I have been messing with to confront some of the issues I have with path finding on grids, usually this is that the path results always look really rigid and unnatural. Even with path smoothing and all that, you still get these less than human looking movement patterns that always bothered me.

Graph theory

Graphs are interesting, and so is the theory surrounding them.

When it comes to path finding, like A-star, you can apply the algorithm to graphs as well. You can see a really nice live demo of graph based path finding on this Polygonal lab page, until I have what I am making in demo form. Essentially it is about connecting points to each other.

This makes traversing the nodes quite a bit cheaper than grid based path finding because there are less nodes (though there can be more, obviously) but the other benefit is that the neighbors and their nodes can be determined ahead of time, and using other algorithms - like Voronoi diagrams - you can insert/remove cells from the landscape dynamically.

Voronoi Diagrams and Delaunay Triangulation

While I was getting ready to move to Canada I wanted to distract myself from thinking too much and worked on implementing pathfinding across large areas using zones, using Voronoi diagrams.

Voronoi Manhattan Distance

You may know what they look like, and their uses and scope are outside of this article (though the link to Wikipedia is fairly thorough) - but they have a lot of fascinating properties including Delaunay Triangulation by connecting their center points.

Delaunay Triangulation

Back to paths!

What I was working on was a small procedural stealth prototype using some code from ctrlr (a post about this generation is forthcoming), to generate a large random space to explore with guards and cameras for interest sake. A procedural stealth playground.

Procedural Stealth Playground

Looking closer you can see there are some guards and some cameras and the building shapes are all random.

Stealthy

Stealhier

The pathing setup

So, to have a guard meaningfully run from one side of the world to another was an interesting challenge, there is of course more than one viable approach - I went with zones (larger cells, like broadphase) and then smaller phase, using the graphs.

At first I tried making the areas a single mesh, but there were just too many nodes for my liking and on larger areas this just got slower and slower. Not ideal.

Voronoi graph and Delaunay triangle mesh

The first step would be to section off areas, and do path finding on the large scale grid, when travelling across boundaries. Like this :

Boundary Broadphase paths

Now the AI can path first on a coarse grid, find the sub grids to navigate, and only ask those sub grids for a path on arriving at their boundary.

This also means that when a destination changes, it is often not significant enough to affect their sub grid path and they won't "suddenly change their mind" and run in a different direction, they will continue until their next boundary arrives unless their next boundary location changes.

Now we have split section boundaries, a decent amount of nodes to generate paths with, and "global" vs "local" navigation running.

gray boxes

Determine your cell location

Clicking on a cell (or deciding where your exact cell location is), in order to find a path, I also used the broadphase cell split approach. Break down each local section into a grid, calculate which grid you are in, and at creation of the grid, store every point and center point of the cell that lies inside the grid in a list. I stored these as list of vertices (to use with a "point in polygon" algorithm).

So when you click on the bottom, you get something like row 6, and column 2. Work out the position in world space, add it by the cell sizes (simple grid math) and check the list of cells for the on it lands inside.

Cell selection

The blue lines are any cell that has a vertex inside of the chose grid location (the third one from the bottom left). The vertices highlighted show the polygon selected, and the white point is the click position. To the path finding!

Neighbors and heuristics

A-star is simple in that it works on a lot of stuff, it's just an algorithm and can be applied to multiple situations. Here we have a start cell, and an end cell - and thanks to Voronoi cells being the basis, we now have Delaunay Triangles (connecting the center of each cell to the other center points) we have the information we already need - the neighbors and the distance for finding a path.

Path Directions

So as you can see, we have a possible direction to go from here. Voronoi can be tweaked to have less or more cell sides, depending on the complexity of your diagram and source points (which is covered later on). The key here is that everything you need to find a path, is sort of inherent to having it being built as a graph in the first place!

Finally, a path

Here is what a path looks like from A to B on this grid (A bit dark, sorry but that was because I was jamming on the code and just taking screenshots along the way).

Path


The drunken stealth guard

So cool, we have a path. It looks a whole lot more natural than a normal grid based path, to me. It is quite rough still, but you could increase the fidelity of the graph and make it higher resolution so that the path is smoother. Like this :

Neat natural paths

That's one approach, but what if you had ... almost a grid? And what if that almost-grid used the same graph theory, just on a more concise set of points? Well, this is what happens :

Natural Paths

I REALLY like this path compared to grids. It's basically a grid! But the results are so much better, and cheaper (thanks to the graph theory having all the data on hand for me).

I still like the results with a messier grid :

Voronoi Paths

But I really like the results of the slightly neater grid as well :

Voronoi Paths

Generating the graph

To generate these spaces, for the Voronoi looking cells - simply place points randomly in the area, and then run a smoothing algorithm over the points using something similar to Lloyd's Algorithm, this neatens up the really random placements into more uniform placements.

Before smoothing :
unsmoothed graph

After smoothing :
smoothed graph

To make the "almost grid" it is as it sounds, generate a set of points on a grid but add a slight amount of randomness to their position. Generate a uniform grid, and then add some noise.

point.x += (-0.5 + Math.random()) * noise_scale;

would give you ~2 pixels of randomness of noise_scale was 2. The -0.5 will make it + / - instead of just + so that the randomness is not shifting the grid to the right and downward. For those unfamiliar, Math.random returns a random number between 0 and 1 (like 0.23953148096).

Other pathing experiments

I have a few more path experiments that I have been exploring over time, some of which I stumbled upon due to buggy Heap algorithm code, and followed the rabbit hole because the results were pretty interesting.

The interesting thing about the following experiments, is that they all still reach the destination (the pathing is 100% ok) but the resulting paths are fascinating.

The path starts at the top left, and ends bottom right. The orange is the grid, the black are obstacles, the white is the path.

Crazy Path 1

Crazy Path 2

Crazy Path 3

Crazy Path 4

Some of the comments on these images were interesting as well, mentioning the last one looking like an optimal tower defense layout. My thoughts once digging into the results were around guard patrol routes, where your job is as a stealth security patrol, instead of being completely predictable you could be more interesting and varied while still maintaining your destination.

Explosions

Things don't always go according to plan (the above is one of those times it works out for the better) but these are some images of when the pathing or graphs were going crazy.

Bad point in cell collection

point fail

Failed "radius" point-in-cell check

Looked neat though!
point fail

Failed Voronoi diagram

voronoi fail

uhhh... what

voronoi fail

Conclusion / resources

I also really like the paths from Theta* path finding, it is a nice way to generate smoother more sensible looking paths.

Alex May linked to an interesting video using tree like paths. This makes me wonder about using L-system generated paths as well... Something I may mess with in future.

]]>