Pokitbeasts (open rpg project)

pokitbeasts

pokitbeasts is an opensource rpg project, in the style of JRPG’s like final fantasy, dragonquest and pokémon.
this tread is meant to manige the project with the community and orgenize

pokitbeasts project is avalable on github

currently looking for:

  • music artists (chiptune/tracker)
  • pixel artists
  • programmers

if you wish to apply for any of these, please post it here.

please note: any art or work you share on this tread will be asumed as CC0 public domain
4 Likes

For public record, I’m currently actively advising on this project.
I don’t know if I’ll be able to contribute much programming-wise because of other projects but I intend to stay as an on-and-off advisor.

1 Like

Very excited about this! As I said, this to me is the ultimate Pokitto game.

Could you specify what art are you needing? I.e. tile size, color palette, style (reference screenshots from existing games etc.). I can’t say I could join the team officially as I have multiple other projects going on, but sometimes I have a bit of free time and might be able to create some pixel art according to what you need, then post it here – in which case you can simply take it or leave it depending on whether you like it or not.

im currently testing 64x64 sprites with there own 16 color pallets only qwerk is that the background color has to also be the top left pixel to ditect it.

only specification right now is that the beasts have to be fantasy based and not modern times

1 Like

That seems really arbitrary.
Why not just dedicate ‘colour 0’ as the background colour?

its creating the color pallet from the image so first come first served
also im looking at 64x64 and it seems small on the screen, might go bigger, is 128x128 to big?

The game or the sprite tool?

16KB assuming one byte per… whatever that’s a multiple of.


One moment, I’m going to post some of the useful stuff I said in the PM for others to comb through.

Sorry in advance because a lot of this is going to seem out of context.
I’m posting this so everyone’s on the same page about what’s been suggested so far.


The subfolders thing isn’t as much of an issue if you’re willing to try to pack multiple files into a single file.
Remember that directories are actually files themselves.
They’re basically files that contain a list of files.

You could have .map files that contain a mixture of dialogue and tile data, or even jam everything into one giant file, which is what a number of triple-A games do.


To be honest though, rather than insisting on a fast SD system, I’d suggest looking into how you partition your world.
Knowing how big you can realistically make a map and how you can divide your map into chunks is useful.

For example, a 256x256 map is 65536, which would be 64KB at 1 byte per tile, so that’s obviously far beyond what you can fit in memory at once.

64x64 is 4096, which would be 4KB, which is a more realistic size.


Before you go diving in to working with code, make sure you’ve got some designs available, especially if you’re going to have lots of people working with you.
Making some prototypes/mockups to test how viable something is would be a good idea, but you’ll struggle to be producive if you’re trying to figure out how the game’s going to work at the same time as you’re programming it.


Instead of having a 2D array, I’d recommend having a flat array for the map.
(If you need help with that, I’ve done that before 1.)

Then you can make your map file essentially be a flat array of chunks.

Then your code mostly becomes something like this:

class Chunk
{
public:
	static constexpr std::size_t Width = 32;
	static constexpr std::size_t Height = 32;
	static constexpr std::size_t Size = Width * Height;
	
private:
	std::uint8_t buffer[Size];
	
	static std::size_t flattenIndex(uint16_t x, uint16_t y)
	{
		// Compiler optimises the multiply to be a shift when Width is a power of two
		return x + (y * Width);
	}
	
public:
	std::uint8_t * getBuffer(void)
	{
		return this->buffer;
	}
	
	std::uint8_t get(uint16_t x, uint16_t y) const
	{
		return this->buffer[flattenIndex(x, y)];
	}
};
class Map
{
public:
	static constexpr std::size_t Width = 256;
	static constexpr std::size_t Height = 256;
	static constexpr std::size_t Size = Width * Height;
	
	static constexpr std::size_t WidthInChunks = Width / Chunk::Width;
	static constexpr std::size_t HeightInChunks = Height / Chunk::Height;
	static constexpr std::size_t SizeInChunks = WidthInChunks * HeightInChunks;
	
private:
	// File management info
	
public:
	void loadChunk(Chunk & chunk, uint16_t chunkX, uint16_t chunkY)
	{
		const std::size_t chunkOffset = chunkX + (chunkY * WidthInChunks);
		fileSeekAbsolute(chunkOffset);
		fileReadBytes(chunk.getBuffer(), Chunk::Size);
	}
};

Note in particular that you only have to seek once to load a chunk.
If seeking is the bottleneck then that will be a huge improvement (hopefully).


This diagram may help (if you can’t read it, I can redo it in paint):

MapSystem

I’ve spent a lot of time researching RPG map structure.
Essentially you’re looking at the same sort of relationships repeated several times at different levels.
(It’s like a sort of dimensionality. Almost like 4D, but not quite. Very meta though.)

Thinking about the structure of the system is key to optimising it.

32x32 = 1024 bytes, and if you need 4-9 in memory at once, that’s 4-9KB.


Never be afraid to shift work onto the map creation tool.
The more preprocessing you do, the less work the game itself has to do.

If you need to have variable sized maps then you’ll have to change the map format to accomodate that, perhaps by putting the sizes in the header of the file.
Unfortunately there’s no way out of designing file formats when making an RPG, you’re going to have to have to have structured files at some point.
(Map width and height will no longer be constexpr and the code I posted would need a lot of modification.)


If you haven’t looked at it yet, have a look at some tutorials of how to use Pokemon Advance Map, it’s a mapping tool for hacking Pokemon ROMs.
I’m not suggesting to use it for this game, but seeing how the tool works will give you a better idea of how Pokemon’s maps work and how they handle things like scripted tiles and warp points.


It would depend on what the constraints of your story are and what you actually need to happen.

Pokemon uses a bytecode system similar to Mother3.
There’s a way to printing text (either a code for ‘start text’ and a code for ‘end text’ or simply treating each text character as a ‘print char’ command that prints a specific character), a way for giving the player items, a way for giving the player Pokemon etc.

(Skyrim uses a similar system, but it’s more focused on dialogue trees and treats text and code completely separately.)

Edit: Aha, here’s a list of Pokemon commands:

http://sphericalice.com/romhacking/documents/script/


Making the environment change based on the story requires some sort of ‘flag’ system. In Pokemon’s case, every event is a bit somewhere in EEPROM and story events toggle those bits.

In the case of Skyrim they have a full quest system where the quest stage is essentially a numerical value and there’s a byte for every quest somewhere in the save data. Typically quest stage 10 is the first stage and quest stage 200 is the last stage (numbers chosen for the same reason BASIC used to number lines in multiples of 10 - to provide room to insert new lines).

I would advise maybe allowing your scripting language to manipulate event tiles and having a ‘map startup’ script that you use to modify the map before the player walks onto it.
Either that or you have to specify in the file format which event flag must be set/clear for an event to be present on the map.


In case anyone can’t tell, I’ve done a lot of research into PRGs :P

3 Likes

just 8KB per sprite + some extra for the pallet
since they are for the battle only im using a different renderer (static images and menu’s)
so im actualy loading the images directly from sd to the mode15 buffer as my storage so im actualy not using any aditional memory for those they can techicaly be the hole screen but that be silly, if posible i would like to do the pokémon thing where you have a front and back of the beast, speaking of pokémon the last game that used sprites had a sprite size of 96x96 so i think i want to stick with 128x128 to enable big looking beasts.

@Pharap question for the battle view i can use the tile buffer wich is 900 bytes for something
any idea what would be usefull there? specific stats and flags prehaps or a script? same aplies for the screen buffer it would have 2.9KB available, would a stack based bytecode work for this?

Is that fast enough?
I thought the SD was a bottleneck?

16KB per sprite, assuming 8bpp.

Still sticking with 30x30 and not 32x32?

It would probably be easier to use dynamic memory for the tile buffer and just dump it when you switch to battle state then reload after the battle.
You can use a full-screen eyecatch as an in-between state.
(I’ve got a feeling that’s what Pokemon did, but I’ve never checked. Perhaps not with dynamic memory, but with emptying the buffer and filling it with new data.)

Any memory can be reused. It’s all just bytes in the end.

SD is not a bottleneck exactly it just has iseus with overworld since im refreshing the 30x30 buffer every 15 tiles you walk wich at the farthest point from the file origin starts to hitch up way more noticably
during battle transition the screen gows black or something and then i can load in the images from the sd card that i need for that battle wich isnt bad at all we talking about like half a second max wich isnt noticeble on a static screen but is very noticeble wen the entire screen is moving and sudnly stops a a few 100 more miliseconds then usual and then continues

still using a pallet so its 4bpp (2 pixels per byte) ending up with 8KB per sprite. its more conveniant/balanced with 15 collors per sprite and it can be any color since its a specific pallet per beast sprite (see directBitmap for more info)

screen width is 220 pixels, tiles are 16pixels so we need around 15 to cover it, to deal with overscan wen moving we double that or we are constantly streaming from sd card, every 15 tiles we reset the position of the tile map on the screen and load the map 15 tiles further.
it gets realy confusing so i reused the same code for the y derection, potential optimization there if memory is getting to short

your right it might be easier but i feel more confedent with static memory alocations that can be reused so i dont leak anywhere (wich with rpgs end up running till your battery is drained might lead to bad things, but im just trying to be carfull and try to stay somewhat performant)

why you think worked on the masks layer thing :wink: have to find 4.7KB memory to do that little gimic

Really we could do with some data on how fast reading from SD card is.
Maybe the reason your original version kept locking up was because you were trying to read so many tiles at once.
Maybe if you only read a single row/column of tiles at a time it would actually be faster.

30x30 is 900 tiles.
A single row or column of 30 is just 30 tiles, so that should take 1/30 of the time to read, which shouldn’t cause a bottleneck.

Dynamic allocation is basically just reusing RAM anyway.

That’s what destructors are for.

If you use smart pointers (specifically std::shared_ptr) then the memory is released when all std::shared_ptrs pointing to the same resource fall out of scope or are reassigned (e.g. assigned nullptr).

(See also: this.)

You could even just leave all the dynamic allocation to the state system, i.e. each state is dynamically allocated, but all the data in the state is not.

I’d say either of those is safer than trying to reuse the same buffer for a different purpose (unless you’re doing something like pooling buffers).

There’s probably an easier way, but it depends how big the screen buffer is and how costly streaming from the SD card is.
To be honest I think just filling the screen buffer with some kind of pattern and then not clearing the buffer would be a lot easier.

(In fact not clearing the buffer would probably make the mask thing much easier too.)

If all your reads are a multiple of 512 bytes and 512-byte aligned you should see a significant speedup.
If your map consists of 900 byte chunks, add some padding to make it 1024. If there’s a header before that, add padding to it too.

If you’re using SDFileSystem, I think you can disable CRC checks since they also slow things down.

Edit: On the subject of CRC checks, we should probably change SDFileSystem to use the CRC engine that’s built in to the processor.

ok so im already there with those wen i trigger my test battle it turns my isBattle boolean on wich is also passed to game update to disable the screen clearing the buffer, i also turn on game.display.presistance so the screen is no static showing the last frame of the image buffer, i then load in the test sprite from the sdcard wich is in the same file as the mapdata aswell as its pallet. from there i got everything setup i could draw the swerl transitionand present the battle screen with the new graphics

more on dynamic buffers:

im still not super sold on these atleast for the tile memory and the screen buffer realocating seem more of a hassle right now then anything else, i do see it to be usefull for text and similar.

giving some more atention to artwork:

still looking for artists btw, if your interested :wink:

im in desprerate need for some beasts i have been trying myself but results are less then stellar.
but to show my cards heres my process:

first off i did reseurch, looking at foxes and dogs moslty
i liked the super pointy ears that reminded me of lynx and i found the idea of a dog about to anticipate and attack to be a good pose.

so then i started drawing a outline, it helped with the general composition not bieng to worried about details
lunsicSHADOW
then i drew a rough line art from then
lunsicline
and started filling in with some color
lunsic

im not that happy with the look atm and will most likly rework this hole beasts design

2 Likes

i started the project with SDFileSystem (on mbed os compiler) wich is the one that randomly locked up after some time of gameplay

i have now with bieng in talks to @Pharap using pokittoDisk (wich is pff wreaper or something) wich is working very nicely in terms of strabilaty and speed the only problem i have is i cant have 2 files open at once wich i would like to be able to save the game wile not corupting the data file, (also i would have like to put both tose files in a folder like pokitbeast.pok so it would not polute the sd card with random game files

@FManga the only speed problem i have noticed so far is from fileSeekAbsolute wen having to load a part of the map thats very deep in the file (around the 200-256KB in the file)

Looks great to me, needs just some cleaning. Is dithering allowed? And antialiasing?

If you’re using smart pointers then most of the time it’s easier and safer than raw pointers and you don’t have to worry too much about when the memory is cleaned up.

If you used a variant of the state pattern then you wouldn’t have to worry as much, you’d just give each state what it needs to work and only the states would be dynamically allocated.

For things like text (I assuming you’re thinking of sprintf and ‘friends’), if a buffer is needed then it’s usually better to allocate on the stack rather than the heap if the buffer is short lived.

if you can do it within the specification of a 15 color pallet i dont see why not, if you want you can edit that beast if you need something to test on :slight_smile:

i keep forgeting i have that book on design paterns, realy need to read that XD