Ardumon Mockup Image

I don’t even have a general idea, but I’m pretty sure it does because lit pixels draw power but unlit pixels don’t.

It can also use less memory in certain circumstances because columns of black pixels around the edge of an image are essentially waste.

Things with white backgrounds can be adapted to black:

BlackBack

Which one?

This one?

Or this one?

Thanks. Might need a bit more freezing though.

Agreed.

Most sprites need to go through a few revisions as well.

SnailLand2
SnailLand2

Sometimes having more than one person contribute to a sprite works better.

1 Like

I guess when you put that into consideration, it would be beneficial overall.

I’d go with the one that has the rounded six teeth ( the second one).

You’re welcome, and also true. You should add it in if you can.

Exactly. I hope a good portion of the community could contribute to this game in some way if it were to come to being.

1 Like

On the Arduboy, because of the way the screen format is, images are stored in columns of 8 pixels, so it pays for them to be multiples of 8 vertically, but not horizontally, so if it turns out at the end that all the 32x32 images could fit into 32x31, that would save 4 bytes per image (assuming compression isn’t being used).

Good, that’s my prefered one too.

The best I can think to do it throw in some snowflakes:

SnailLand3

I concur.

1 Like

Why not just let the player have the option to invert the game from a menu?

1 Like

That could also work if it isn’t a hassle to inplement.

So something like this?
59
So telling from the image, it’s a 8x16 image, and let’s say that the red is nothing more than blank. So what you’re saying is if it isn’t utilizing the most right columns, it doesn’t even need to be added and the image can just be 7x16, correct? Also, can it be stored as decimals instead of just hexidecimal?

Perfect! This will make @Freezingsnail proud!

Edit: What if you call it Salinkryo. It’s the combinations of the word Kryo, ( spelled κρύο in greek) which means cold, and salinkari, ( spelled σαλιγκάρι in greek) which means snail. I used google translate to get the words.

Edit2: Also along with sprites, we should come up with original move concepts.
And also, Would you also say that battle animations are necessary, like fire being blasted at the enemy when using a fire move?

Edit 3: The Prequel ( joke):
I’ve made my version of @Freezingsnail’s, well, snail. Here are the variations
dotpict_20180415_145115dotpict_20180415_145203dotpict_20180415_145229dotpict_20180415_145317
The difference between them all are the eyes.

I also found this design while searching in google frozen snails ( if you love snails, don’t search that up). It looks like something that could also be adapted.
snowshell_sm

4 Likes

The name comes from a adjective noun generator, like the xbox live suggest a name use to spit out.
squidu2

I’ll leave the other sprites I make up to interpretation as who they may be for.
pilmote

Unfortunately sprites are also not my strong point.

4 Likes

Interesting. My name is simply my last name backwards.

They look pretty good in my opinion. Spookuid is just a name that I’ve came up literally now for the first one. And the second one. Hmmm… Mr.Krabs. No, I’m joking. How about Crabjoy? I don’t know, I’m bad at naming.

1 Like

Hang on, I’ll dig Emuty’s image out…
It works like this:

Image Format

Hence a column of block is just a block of 0x00, which is essentially a waste which can be trimmed off.

Essentially yes.

If the image was going to be drawn with a mask then the black background would probably be cut off anyway.
If the image was going to be drawn solidly then it’s usually possible to draw a black rectangle beforehand.

It does depend on the circumstances, but usually cropping images one way or another ends up being cheaper in the long run…

Yes, but really there’s no difference.
Decimal, hexadecimal and binary are all just different ways of representing the same thing.
In the end it will all be converted into binary so that the computer (the Arduboy) can understand it.

If you don’t yet understand hexadecimal or binary, have a read of this, it’s my favourite introduction to binary and hex.
(So much so that I’ve added it to my resource collection.)


Could work.

Really I think if we’re going to be basing characters on people on the forum it would be best to get them to either choose or accept the name, so it probably doesn’t matter much whether I like it or not, it would be up to @Freezingsnail.

(Kryokali is also an option :P.)

Yep, as in cryogenesis, cryostasis and cryokinesis

I guessed that’s what it would be.

(Salinkari is also an island in Finland aparently.)

That would take a massive chunk of memory, so if there were animations I think it would be best to restrict the animations to just simple things matching the element of the move.

I think the shell is a big improvement.

I prefer the first three but don’t have a particular favourite out of those.

I found where it comes from. Strange website.


It’s a little hard to tell what they are because of the detail.
Looks like a squid with skull markings and a crab with odd markings on the front.

If in doubt, portmanteaus.
With a few exceptions like Ekans and Roggenrola, most Pokemon names are portmanteaus (e.g. infernape = inferno + ape, rhyhorn = rhino + horn, articuno = arctic + uno).

2 Likes

Aww man. All of this brainstorming just makes me want this game to happen already! It’ll take a long time though, if it’s going to happen at all.

4 Likes

That’s the gist of it.

Also I was thinking about how type bonus could be implemented last night, as I’m also trying add that in the project I’ve been working on. I was thinking of using an array along this line

int effectivenessMatrix[] = 
              f    w   e   f   water/flying    //target types
fire        { 1,  .5,  1,  1,  .5,
water         2,   1,  1,  1,   1,
electric      1,   2,  1,  2,   4,
flying        1,   1,  1,  1,   1 }
//^ attack types

And then using enums you could pull out the modifier:

enum types :  int {
  fire  //0
  water //1
  electric //2
  flying //3 
  water/flying //4

int getEffectivenessModifier( types attack, types target){    //water , fire
//(attack * total number of types ) * target
  index = ((static_cast<int>(attack) * 5 ) + static_cast<int>(target));  //((1 * 5 ) + 0 ) = 5
  return effectivenessMatrix[index];  // returns 2 for 2x damage.
}

This is also definitely better than how I had first planned it out in my project (forloops running through a list)

2 Likes

I learned Binary once, but I forgot it. I’ll use your link to refresh my memory while learning hex. Thankyou. :slight_smile:

True, it’s up to @Freezingsnail to decide that. Kryokali is also a really good name.

I saw that too when I was searching up salinkari. That’s a funny coincidence.

I guess it would be best to keep it simple then if it was able to be fitted.

Thankyou. I like the first one, but the third one’s a close second.

Haha, that’s hilarious. I gotta check that out.

True. I’ll keep that in mind.

3 Likes

Why not brainstorm with us, @LambKnight? The more, the merrier!

2 Likes

Pseudo code I’m guessing?
You can’t store .5 in an int (or at least not like that).

The general idea is close.
I’ll write something and post it when I’m done.

2 Likes

Yea I know you can’t have decimals, otherwise it wouldn’t be an integer. It could be -1 or something else, it really doesn’t matter what that numbers are since theres no damage formula to plug them in. Or you could just double all of the numbers and then have the modifier over 2 in the equation as a simple fix.

2 Likes
enum class Type : uint8_t
{
  None,
  Fire,
  Water,
  Electric,
  Wind,
};

constexpr const uint8_t TypeCount = 4;

class DualType
{
private:
	uint8_t value;

	constexpr const uint8_t Type1Mask = 0x0F;
	constexpr const uint8_t Type2Mask = 0x0F;
	constexpr const uint8_t Type1Shift = 0;
	constexpr const uint8_t Type2Shift = 4;

	constexpr uint8_t packTypes(Type type1, Type type2)
	{
		return ((static_cast<uint8_t>(type1) & Type1Mask) << Type1Shift) | ((static_cast<uint8_t>(type2) & Type2Mask) << Type2Shift);
	}
  
public:
	constexpr DualType(Type type) : value(packTypes(type, Type::None)) {}
	constexpr DualType(Type type1, Type type2) : value(packTypes(type1, type2)) {}
	
	constexpr Type getType1(void) const
	{
		return static_cast<Type>((this->value >> Type1Shift) & Type1Mask);
	}
	
	constexpr Type getType2(void) const
	{
		return static_cast<Type>((this->value >> Type2Shift) & Type2Mask);
	}
};

enum class Modifier : uint8_t
{
	Same,
	Half,
	Double,
	Quarter,
	Quadruple,
};

uint16_t applyModifier(uint16_t value, Modifier modifier)
{
	switch(modifier)
	{
		case Modifier::Same: return value;
		case Modifier::Half: return value >> 1;
		case Modifier::Double: return value << 1;
		case Modifier::Quarter: return value >> 2;
		case Modifier::Quadruple: return value << 2;
		default: return value;
	}
}

Modifier typeTable[TypeCount][TypeCount] PROGMEM =
{
	// Fire
	{
		Modifier::Half, // Fire
		Modifier::Quarter, // Water
		Modifier::Same, // Electric
		Modifier::Double, // Wind
	},
	// Water
	{
		Modifier::Double, // Fire
		Modifier::Same, // Water
		Modifier::Same, // Electric
		Modifier::Half, // Wind
	},
	// Electric
	{
		Modifier::Same, // Fire
		Modifier::Quadruple, // Water
		Modifier::Same, // Electric
		Modifier::Half, // Wind
	},
	// Wind
	{
		Modifier::Half, // Fire
		Modifier::Double, // Water
		Modifier::Same, // Electric
		Modifier::Half, // Wind
	},
};


Modifier getModifier(Type attackType, Type defendingType)
{
	return (attackType == Type::None || defendingType == Type::None)
	? Modifier::None :
	static_cast<Modifier>(pgm_read_byte(&typeTable[static_cast<uint8_t>(attackType)][static_cast<uint8_t>(defendingType)]));
}

uint16_t handleAttack(uint16_t baseValue, Type attackType, DualType defendingType)
{
	const Modifier mod1 = getModifier(attackType, defendingType.getType1());
	baseValue = applyModifier(baseValue, mod1);
	const Modifier mod2 = getModifier(attackType, defendingType.getType2());
	baseValue = applyModifier(baseValue, mod2);
	return baseValue;
}

This is a start at least.

2 Likes

The only thing I think I prefer is having the dual types just be their own thing like in my example since I didn’t want to use a 2d array. I guess it would depend on the total number of types and dual types though. If there’s 16 base types I see how your method would make more sense since there’s so many combinations it wouldn’t be practical to have 100s of enums. At the same time that would be necessary though assuming there’s only 30 monster, as at most you could only have 30 different combinations of types. Which still is a large amount. More realistically you could assume there would be at least 2 of each type for most cases which could lower that to an estimate of maybe 15-20 different type combinations.

Just as another note, you wouldn’t necessarily need the quad and quarter enums as the effective bonus is only 1, 2, or .5 which is stacked through multiplication. This is strictly cloning the mechanic though, and you have wind resisting electric so that’s clearly not your case in that example.

1 Like

Dual types don’t affect the need for a 2D array.
The 2D array comes about because you have an attacking type and a defending type.

If DualType wasn’t involved, the only difference would be that this:

uint16_t handleAttack(uint16_t baseValue, Type attackType, DualType defendingType)
{
	const Modifier mod1 = getModifier(attackType, defendingType.getType1());
	baseValue = applyModifier(baseValue, mod1);
	const Modifier mod2 = getModifier(attackType, defendingType.getType2());
	baseValue = applyModifier(baseValue, mod2);
	return baseValue;
}

Becomes this:

uint16_t handleAttack(uint16_t baseValue, Type attackType, Type defendingType)
{
	const Modifier mod = getModifier(attackType, defendingType);
	const uint16_t value = applyModifier(baseValue, mod);
	return value;
}

Your original table had a 4 in it, so I just assumed.

If there were only going to be x1, x2 and x0.5 then yes, that could be reduced.

This is before the main body of optimisation anyway, the small pool of modifiers would allow for more than one modifier per byte so that table could be crushed smaller anyway.

I just picked some random stuff for demonstration purposes.

I changed flying to wind to go closer to the classical elements rather than trying to be an outright clone.

2 Likes

The 4 was for the water/flying dual type, since it would be 2*2, but there’s no stacking in my method so you need the 4. Yours stacks and is also probably a lot closer to the actual funtion in the 'mon games.
Also I forgot the nullifying case now that I think about it that’s just immune -> x0

1 Like

More importantly the stacking approach doesn’t use as much memory.

One of the golden rules of memory saving is “don’t pre-calculate what you can calculate on the fly”, which is sort of the antithesis to the speed rule of “pre-calculate what’s costly to calculate”.

That’s easily added:

enum class Modifier : uint8_t
{
	Same,
	None,
	Half,
	Double,
	Quarter,
	Quadruple,
};

uint16_t applyModifier(uint16_t value, Modifier modifier)
{
	switch(modifier)
	{
		case Modifier::Same: return value;
		case Modifier::None: return 0;
		case Modifier::Half: return value >> 1;
		case Modifier::Double: return value << 1;
		case Modifier::Quarter: return value >> 2;
		case Modifier::Quadruple: return value << 2;
		default: return value;
	}
}
1 Like