Help me with C++ for my game


(Boti Kis) #243

I just watched the whole video and it’s amazing. Just learned a couple of great things in c++. thanks again @Pharap.


(Pharap) #244

There’s TypeScript.

It’s basically JavaScript with static typing and it ‘compiles’ to JavaScript.
(One of the developers who as worked on it was the lead architect of C#, and C# is a glorious language, so I hold out hope.)

Personally I think it’s a bit of a ‘patchwork’ job and that ultimately the problem is that there’s still JavaScript underneath, but JavaScript is so ingrained now that I think this sort of thing is the best I can hope for.

I remember that feeling.

Really long anecdote

When I was in college they taught us Visual Basic in class.
I can’t remember how or why but I started learning C# in my spare time because I was enjoying the programming module and wanted to learn more than what we were doing in class.

At that point I’d heard the typical legends about C++.
How it’s supposedly one of the most important languages in the software industry,
and how it’s supposedly really difficult to learn.

Because of the supposed difficulty I put off learning it, but then I met this guy.
To this day I don’t know what his name is or what he was doing there;
he could have been another student, he could have been a member of staff.

I got talking to him, and he said to me “I write games in C++ and it’s not as hard as everyone makes it out to be”,
and he showed me a website called toymaker (unfortunately it’s ‘dead’ now) which had a few C++ tutorials on it.
I said to him “I’ve been thinking about giving C++ a try, but I don’t think I’d be very good at it”,
and he said to me “I think you’d be able to do it, I hear you’re already quite good with C#, and it’s quite similar in places”.

I didn’t actually read much of the toymaker tutorials, but as a result of that conversation I decided that I should give C++ a go, so I started reading into it.

Many thousands of articles and throwaway programs later and I suddenly realised “Hang on, I understand C++!”.

For years of my life I’d been without any kind of talent or skill,
and there I was - able to understand this legendary language that I’d always believed would be too difficult for me to understand.

Words alone cannot express how that felt.
Learning to program has given me a greater sense of acomplishment than anything else in my life.

I’d really like to try to find out who that guy was someday and thank him.
I probably would have ended up learning C++ anyway,
but simply having someone say to you “I think you can do this” can make all the difference.
A bit of encouragement goes a long way.

It also uses a weird visual scripting language.

I’ve never got round to trying UE.
(In all honesty I prefer 2D games most of the time. 3D is just another dimension worth of bugs to fix. :P)

Don’t thank me, thank Bjarne Stroustrup for having done the talk in the first place.

Also, be sure to spread it around and encourage others to watch it.
Hopefully it will enlighten a few people, or change some people’s opinions.


#245

There might be a way to have run length encoding fast enough that I don’t need to load a level/area in RAM at all. (not sure how promising that looks)

you may store the location of the run in the array. For example, the string AAABBBBBZWWK becomes 1A-4B-9Z-10W-11K. The benefit of this approach is to allow random access in logarithmic time using binary search. However, it is also incompatible with some techniques to avoid unnecessary counters. So, it is a compression-speed trade-off. For even more speed, you can store both the location of the run and its length (thus avoiding a subtraction).

Source: https://lemire.me/blog/2009/11/24/run-length-encoding-part-i/

By the way, I’ll probably end up not using most of these sprites

I mostly did them to practice, before I started actually making the game. But I need t show them off at least once

Definitely was worth a read. I love stories like this


(Pharap) #246

It’s possible, but I think the code to achieve it would be an utter mess.

I think it’s worth at least leading part of the level into RAM because you’d need it for both drawing and collision checking.

Reading RLE data as if it were raw grid data is going to be expensive,
so it makes sense to sacrifice some RAM so you only have to do it once.

But then the Arduboy’s CPU is quite fast despite its relatively low spec.

That’s using 1-indexing instead of 0-indexing.

This makes sense, but logarithmic time is worse than constant time (which is what reading from RAM would be).

Fortunately the actual drawing phase should be roughly the same for both approaches.

Again, it’s possible, but the code is going to be quite a bit more complicated than simply loading chunks into RAM.

I think the sequel should be a mario-like game just for the sake of being able to use these sprites.

I think having fewer levels is worth it if there are obstacles and powerups.

In a way I guess it explains why I spend more time helping other people than I spend writing my own games.


#247

One thing that worries me about loading it into RAM is the player’s death

It’s very important to re-spawn instantly and be able to try again right away, no waiting. One solution might be to have the start of the level uncompressed

This is a tiny thing that might seem unimportant, but it’s what makes many addictive games addictive. They don’t ask you if you want to restart, there’s no delay, you can try again right away. The penalty of death is to get to play again, not to wait

I’ll have to test it and see how it goes


(Pharap) #248

Remember you’d only be uncompressing (at most) a screen worth of information, not the entire level.
If you’re using 8x8 tiles that’s 128 tiles in total.
The RLE representation would be smaller than 128 raw tile indices,
so we’re talking just a few bytes.


#249

(I was editing my other comment when you posted this)

If I use 4 bits per tile, a level of 160tiles wide and 8 tiles high would take 1024 bytes. I could have about 10 levels. But, since there’s a lot of duplicate tiles (mostly air), I could use run length encoding, per section to load things quickly in RAM. Quick edit: if I use run length encoding I don’t have to limit myself to a 16tileset

Maybe it could end up with quite a few levels and still looking great.

I think I’ll do as you suggested, finish this “super-hard, tons of levels” version of the game then make an adventure/mario like version with the rest of the sprites

Other quick edit:

I’m wondering if there’s a nice way to store trees for my RPG. ithere are 4 tiles, but they’re in a pattern
One Idea I didn’t think about before is having “layouts” that I reuse. I’m also gonna look into perlin noise again. Now That I’m more familiar with your fixed point library, it might become feasable

I want to finish and polish my platformer first however. It’s almost ready, only missing a menu, some stats variables. Well okay, it’s missing a lot. But still, should be ready soon

Edit: here’s the perlin noise article I’m reading


(Pharap) #250

Again though, that’s a fully unpacked level.
A single screen would be much smaller.

Theoretically yes, but using more tiles will increase your data size even if you use RLE.

If you unpacked a local area into RAM (like I’ve been suggesting for this platformer) then you could store trees as just a point (their location) and a type (tree, as opposed to rock).

The difficult part would be locating the data that needed to be loaded as you travelled around the world.
I think you’d need to store your objects sorted by coordinate.

Speaking of which, if you need sine and cosine functions, I know a way to make those, but only using brads (as opposed to radians).

I started looking into making some other common floating point functions for fixed points,
but I got a bit lost around “taylor series” and “euler’s method”.

Proper perlin noise requires a 256 element lookup table.
Or at least, the canonical implementation of the improved version does:
https://mrl.nyu.edu/~perlin/noise/

I’m not a big fan of ‘eevee’.

They’re a decent enough programmer, but as a person I find them a tad annoying,
and I’m not particularly fond of their writing style either.

The article I most like for Perlin noise is this:
https://flafla2.github.io/2014/08/09/perlinnoise.html

Which is an updated version of this:
https://mzucker.github.io/html/perlin-noise-math-faq.html

The former link has some links to other useful articles,
but notes that some of them aren’t actually Perlin noise.
Ultimately when it comes to noise it’s the result that’s the most important thing.
(Whether or not it’s actually Perlin noise is purely academic.)


#251

One thing that might work is loading the level from left to right, then top to bottom. And having one number represent the top left of a tree tile. Then, when loading it in RAM replacing the top right, bottom right and bottom left tile with the rest of the tree (in RAM, thus not affecting the original source)

You go to the next row, there’s another top_left tree tile, it overwrites whatever tree tile is behind itself, making it all tile properly. Wait that would still not work too well because it wouldn’t all just be 1s…

Maybe you’re right about storing trees seperately. I’ll keep thinking about this

Thanks for the link to those articles. I was hoping you’d point me to nice references, to help me understand the type of problem I’m dealing with… this originally wasn’t intended to be a bunch of puns, just a thanks. The child in me took over

Brads are fine with me (you mentioned it before and I looked it up, and it’d be perfect for me)

I might not need something as powerful as Perlin noise. If I seperate environment generation from structures/“levels” generation, I might be able to use something much simpler

Edit: as a note, I can do cave generation with cellular automata. I’ve done it before, the problem is you need to iterate multiple times, I don’t think it’d be fast enough. Although I suppose it could be worth trying, could work for a forest layout. If the view moves in chunks of 128x64, and I have a tiny “loading transition” it could theoretically work fine, or it could work for a different type of game

Edit2: actually if I go back to my original idea, being only a dungeon crawler/dungeon escape with a lot of traps and some enemies, and I use cellular automata for level generation… that would leave a ton of space for my sprites, and I could have my beautiful sword slash animations, and other nice enemy sprites :D

Nice sword animation… nice overworld… tough choice, tough choice. (half-kidding, a nice overworld is great if not excellent, but I do love my sword animation a lot)

Edit3: 1D noise incoming…


(Pharap) #252

I should really remember to put these in my resource collection.

Pointing and types… a few crafty references to C++.

I did? Well that saves me an explanation. :P

Drunken walking? :P

It’s possible it would be.
Usually memory is a bigger issue than speed on the Arduboy.

Oh, you’ve just reminded me.
It’s technically not a cellular automaton, but it might help…

Behold, Lindenmeyer Systems:

Squiggly.


#253

Nope! Something that is basically the same to Conway’s Game of Life

You start with random noise on a grid, then on a second grid, you look at the data from the first grid. You look at how many neighbouring values are set to true, and if enough of them are, whatever tile this is becomes true. If not, this tile dies.

This turns random noise into cave-looking areas, would work well for something Terraria-like. Especially since Terraria doesn’t have an infinite world

But now that I think of it, I only need 8*16 tiles in the screen at once. I’m now 100% certain it would work on the Arduboy. I’ll have to go play with cellular automata again afterwards… I never tried playing with anything other than true/false. Maybe with a set of rules complex enough, I can end up with something very cool


#254

I can’t write “now” without ending up writing “not” to save my life.

I made a lot of progress, apparently I understood more about creating noise than I thought I did. I’m now following a video tutorial and following along, and the guy is doing a lot of stuff I already knew about

If I end up making the noise stuff good enough… maybe I can turn it into its own library for the Arduboy :D


(Pharap) #255

That’s a shame, drunken walks are funny.

In all seriousness though they’re not that great so it’s probably a good thing you aren’t using one.

Yep, I’m familiar with that.
I wrote a GOL back in 2014 (I just excavated it from my archive).

I wasn’t aware there was a rule that could make caves.

I suppose it makes sense, but finding rules requires either trial and error or very good mathematical knowledge.


#256

Or a quick “procedural cave generation cellular automata” search on Youtube :D

Or you could just ask me :D (thanks for the tip on making those :D faces by the way)…

Oh and, how do I do code folding? That’d be pretty useful for images

That one was with 13 iterations. The more iterations, the smoother it gets.

At 0 iterations it’s just pure noise, because each tile just gets a random true/false.

Now the cool thing is, if you need it to be fast… do just one iteration, and the result is still pretty good

And here’s at 2 iteration:

Two iterations seems like the perfect trade-off, as it removes almost all “alone” or “rogue” tiles.

Usually you need two grids/two 2d arrays, because you need all the old data to make the new data, but apparently it can work even if you modify the first one directly. However if you need to erase and redo it later, like you would probably do on the Arduboy, then I suppose you need to grids/2d arrays, but they can be small. I had forgotten about this, but as long as you use the same seed to generate noise in a section, you’ll get the same result

It should work, I’ll probably do it just to confirm it. I already have the code and it’s short and simple, it should work

Edit: I’m getting further with Perlin noise…


(Pharap) #257

They’re called ‘details blocks’. You can either use the gear menu and choose ‘hide details’ or just type it out as regular BB code, like so:

[details="Summary"]
Content
[/details]
Summary

Content

Interesting.

You could condense it to be 1 bit per bool.

Very Perliny.


#258

I don’t know why I struggled so much to do this, but I finally got the formula for autotiling my trees.

Any tree, in run length encoding or whatever else, will be stored as the same number - no matter which tile of the tree.

Then, the rules are as follow:

For every tree tile, in a nested for loop, with the outer loop being for Y, and the inner loop being for X.
Well the code will explain itself

for(var j = 0; j < worldHeightInTiles; j++) {
	for(var i = 0; i < worldWidthInTiles; i+=2) {
		if worldWidthInTiles == i continue;
		var _value = (Noise2D(i*0.001, j*0.001, frequency*tileWidth, octaves)+1)/2;
		if (0.99 < _value) {
			var offset = j%2;
			worldGround[# i+offset, j] = _treeTopLeft;
			worldGround[# i+offset+1, j] = _treeTopLeft+1;
			worldGround[# i+offset, j+1] = _treeTopLeft+2;
			worldGround[# i+offset+1, j+1] = _treeTopLeft+3;
		}
	}
}

replace the noise function with simply reading what tile is stored, and the rest stays the same.

The only disadvantage from this is that I have to keep in mind, when editing the world that the resulting trees/forests might be one tile more to the right than anticipated. This is because one tree tile generates 4, being 2x2. The reason it autotiles correctly (the trees higher up appearing tobe behind the trees lower) is because I simply overwrite whatever tree tile has already been loaded.

TL;DR I just gained 3 extra tiles for my Hack N’ Slash RPG, without having to remove my trees or make them smaller.

I tested it with my perlin noise stuff, as it was a good opportunity to do this.
I could do the same for houses; store only the door, generates the rest on the go. BOOM, tree more tiles. I could do the same for my fences. BOOM, tree more tiles. That’s if I keep my world pre-made instead of generating it (but if I generate it, I need auto-tiling anyway.)

Edit:

If I can implement biomes, I can make the trees more seperated so that you can walk in between bunches of trees instead of having to go around them (it has to be in sync with the rest right now otherwise it spawns on water)


(Holmes) #259

Just a cool idea, you know… If you happened to create a SECOND map and overlay it, you could use data from that one to add something like rock formations, buildings, or other non-natural items inside of the land area.


#260

I could use my cave generation algoritm for the forests… or modify my perlin noise for just forests

So many options to try

Edit: I’m apparently using value noise not Perlin noise. Perlin noise is a varient of gradient noise and mine isn’t. It’s just random values and lerping between them, the difference apparently is that gradien/Perlin noise uses a direction vector to add more and smoother variety to the noise generated.

Apparently value noise is pretty good too because that’s what I I’m using right now


#261

Deeper and deeper in the procedural generation rabbit hole… I’m now reading about procedural house generation. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.97.4544&rep=rep1&type=pdf

This was linked to from http://pcg.wikidot.com/pcg-algorithm:city-generation

(I probably won’t use that… but the curiosity is pulling me in)

Using one step of cellular automata, which allows me to not require 2 arrays of the area loaded in ram. This might have potential. I wrote this one on my own so I can easily remake it for the Arduboy. It uses 8 neighbours, so there’s 9 calls to to the noise function per tile

This one uses 4 cell neighbours, still looks good

Picture

If I make it either solid/, non solid, I get this with 8 neighbours:
This one could work well for a forest. There’s enough “walls” that you can and can’t walk through, it could make for a fun exploration.

Picture


(Pharap) #262

I take it you saw the bold in the references section of Understanding Perlin Noise?


Your last picture reminds me of army camo for some reason.