Sign in to follow this  

Unity How to code and use commonly used algorithms

This topic is 4680 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Greetings In this thread place little micro-tutorials on how to code and use commonly used algorithms. For eg. A simple sorting algorithm, a bubble sort. What to use it for What not to use it for Why you should use it Problems with using it ect. I will edit my post to add the algorithms we have already used. Please note that double posts are allowed. Current index: Absolute function Binary search x2 Hash table Simple case boyer-moore string search Memory manager Bitreversing algorithm Recursive Floodfill Algoritithms awaiting a tutorial Complex Boyer-Moore string search algorithm Binary heap Quicksort From, Nice coder [Edited by - Nice Coder on January 9, 2005 4:58:43 AM]

Share this post


Link to post
Share on other sites
Binary search

It searches a sorted array of values, for a particular value in o(log2 n) time (worst case).

This is a very fast search algorithm.
For eg, if you have an array that is 18,446,744,073,709,551,616 elements big, it will find any given element in at most 64 iterations.

Why is it that fast?

It is that fast, because at every comparison, it divides the search space in half. This means that after 2 iterations, the search space is 1/4 of the origional. this allows it to not search most of the array.

You should use it whenever you have an array, and you need to find a given element quickly. for eg, in a search engine, or pretty much anything.

psudocode:

Function binarysearch(array(), Element)
max = upperbound(array)
min = lowerbound(array)

do
Guess = makeinteger((max - min) / 2)

if guess is negitive then return falure

if array[guess] = element then
return guess
elseif array[guess] > Element then
max = guess - 1
elseif array[guess] < element then
min = guess + 1
else
return falure
end if
loop forever


From,
Nice coder

[Edited by - Nice Coder on January 2, 2005 3:53:12 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Nice Coder
Greetings

In this thread place little micro-tutorials on how to code and use commonly used algorithms.

For eg. A simple sorting algorithm, a bubble sort.

What to use it for

What not to use it for

Why you should use it

Problems with using it

ect.



In C++ no doubt: use STL and their algorithm.
For example if you use std::set data structure (in general it is implemented as a binary tree) the method set::insert can be used to insert and/or find an element in O(log2 N) without need to reinvent the wheel.

If you need to sort a sequence use the algorithm sort: no need to specify the type of the sequence (vector, list,...). However if the sequence is a vector the algorithm is O(NlogN ).

Use your own algorithm leads to bad programming...

However if you like to do this I report the classic merge-sort algo for vectors ( O(NlogN) )


// pseudo C code
void Sort(TYPE* vector, INT lo0, INT hi0)
{
if (lo0 >= hi0){
return;
}

INT lo = lo0;
INT hi = hi0;
INT mid = (lo + hi)/2;

while (lo < hi)
{
for(;lo<hi && vector[lo]<vector[mid];lo++);
for(;lo<hi && vector[mid]<vector[hi];hi--);
if (lo < hi)
{
TYPE etmp = vector[lo]:
vector[lo] = vector[hi];
vector[hi] = etmp;
lo++;
hi--;
}
}

if (hi < lo)
{
INT tmp = lo; lo = hi; hi = tmp;
}

Sort(vector, lo0, lo);
Sort(vector, lo == lo0 ? lo+1 : lo, hi0);
}

Share this post


Link to post
Share on other sites
Thats why this is here, so people can have a set of good algorithms, programmed in a language they can use, which contains more algorithms then then the stl.

From,
Nice coder

Share this post


Link to post
Share on other sites
A fast string search.

Time complexity o(n / m) where n is the length of the string that your searching, and m is the length of the string your searching for.

Simple case, where each letter is used only once.

Psudocode:

function stringsearch(text, find)
lof = lengthof(find)
index = lof
do
if the index'th carachter of text is equal to the last character of find then
check backwards, and see if the index - 2'th character of text is the same as the second last character of find.
Continue looping until you have checked the entire string. (Find), against the substring(string, index - lof,lof)
If you find an inequality then go back to the index += statement
otherwise, you have found your
index = index + lof
loop until index is larger then the length of the text


More complex case to follow

From,
Nice coder

Share this post


Link to post
Share on other sites
Your algo is O(n) where n is the sequence lenght because in the >>WORST<< case you do n/m * m = n char tests.
Otherwise if m = n (it is reduced to a string compare) you would have O(1) that is not the case!!!

For those who use std::string there is


starting_index = string.find(substring);



I'm afraid that your algorithm does not work in this case

search for: aaa (len = 3)
in : bbaaa (len = 5)

you start from index=3 and go back -> a[OK], a[OK], b[BAD]
increase index = 3 + 3 = 6 -> 6>5 -> exit -> NOT FOUND -> WRONG!!!

The correct algo is


int search(const text, str)
{
for(int i=0; i<len(text); i++){
if(string_compare_maxnchar(text+i, str, len(str))==equals){
return(i);
}
}
return(-1);
}



where string_compare_maxnchar(const s1,const s2, int n) compares max n char (strncmp in C) -> O(n*m) = O(n) in practical WORST case

Share this post


Link to post
Share on other sites
Quote:
Original post by Nice Coder

Function binarysearch(array(), Element)
max = upperbound(array)
min = lowerbound(array)

do
Guess = makeinteger((max - min) / 2)

if guess is negitive then return falure

if array[guess] = element then
return guess
elseif array[guess] > Element then
max = guess - 1
elseif array[guess] < element then
min = guess + 1
else
return falure
end if
loop forever
A newbies guide to the binary search algorithm: All you thought you knew, and more...

You've made a very common major performance mistake (or two) here.
You've put the most unlikely if case first. The equal case should be the last case. Also since you have then already determined if it was < or > and acted appropriately then it must be equal so there is no test required. This cuts down the number of compares to about half what it was.

In fact, it's actually better if you leave the = part out of the loop entirely, since it's so rare, and only stop when min = max (at which point you will be at the item to compare for equality).
This all cuts it down to 1 compare per iteration, rather than the three you have above (try the biggest item). Performance also levels with exactly logn comparisons each time, rather than between 1 and 3logn (about 2.5logn on average)

Taking the = comparison out of the loop also has the unexpected advantage of making sure that you find the first occurance of an item which has duplicates in the array, which makes it easier to go through all duplicates (should that be of any usefullness in a given situation)
Or, if the item is known to be always present and you just what to find it's index, then the equals test can be removed entirely!

Now the C++ code...
template <class T, class Size, class TKey>
Size BinarySearch(const T a[], Size n, const TKey &find) {
Size l = 0, r = n; //r starts at the item past the last one
while (l < r) {
Size m = (l + r) / 2; //midpoint
if (a[m] < find)
l = m + 1;
else
r = m;
}
if (a[l] == find)
return l;
else
return NOT_FOUND;
}

Sure both are O(logn) so both are relatively fast, but a little extra thought effortlesssly gives you another 2x speedup + added niceities. Feel free to use the code above in your own programs. You may need to overload the < and == operators.
[smile]

No offence intended Nice Coder, just enlightening everybody furthur.

[Edited by - iMalc on January 2, 2005 2:35:17 PM]

Share this post


Link to post
Share on other sites
What to use it for: flipping 2^n bits with n = {0,1,2,3,4,5...}

What not to use it for: everything else

Why you should use it: because it's quick and compact

Problems with using it: none

How to use:
//example: flip last 16 bits of int x (starting at LSB)

int x = 0xfb10a386;
int i;

x = ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8);
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4);
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2);
x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1);

For a how-it-works, see:
http://www.gamedev.net/community/forums/topic.asp?topic_id=291109

Bas

Share this post


Link to post
Share on other sites
Description: recursive function for filling up a map[x][y]

What to use it for: filling up an area in a map, example:

****************************************************************
*###########################*********###########################
*#*************************#*********#*************************#
*#*************************##########**************************#
*#*************************************************************#
*#*************************************************************#
*#*************************************************************#
*#*****############********************************************#
*#*****#**********#********###########*************************#
*#*****#*#########*********#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#*****************#*********#*************************#
*#*****#*#********#########**********#*************************#
*#*****#*#********#******************#*************************#
*#*****#*#********#******************#*************************#
*#*****#*#********#******************#*************************#
*#*****#*#********#******************#*************************#
*#*****#*#********#******************#*************************#
*######**#########*******************##########################*


What not to use it for: filling up a map which is not limited by walls

Why you should use it: because it's very compact and quick; can also be optimalised very effectively using the stack in combination with in-line assembly

Problems with using it: none

How to use:

void fill(unsigned int x, unsigned int y){
if(map[x][y] == '*'){
map[x][y] = '#';
fill(x-1,y); fill(x+1,y); fill(x,y-1); fill(x,y+1);
}
}


For a how-it-works and more information, see:
http://www.gamedev.net/community/forums/topic.asp?topic_id=291495

Bas

Share this post


Link to post
Share on other sites
Imalc: no offence taken. I just usually hand out psudocode that isn't as optimised. Nice code. Too.

Maybe We should also have mini-contests on who can make the most optimised code for the algorithms?


Register int32 l = 0
Register int32 r = n
Register Int32 m = 0
Register int32 f = find

while (l < r) {
m = (l + r) >> 1

if (a[m] < f)
l = m++;
else
r = m--; // -- needed here, to make sure that it terminates.
}
if (a[m] == f)
return m;
else
return NOT_FOUND;


Its a little better. tho it could be a little quicker.

blizzard999 -> Actually it is o(n / m), the origional algorithm.

Because once it hits a letter that isn't in the query string, it jumps the length of the string its trying to find. it then starts again.

For eg.

int *index
char string[strlen]
char find[findlen]
char *flen = find[findlen]
char *fto
int strl = *string[strlen]

index = &string + findlen;
while (index < strl) {
if (index != fto) {
*Index = &index + findlen;
*fto = &flen;
Continue;
} else {
if (&fto > &find) {
*fto = &fto--;
Continue;
};
// sucess
return &index - &string
};
};
};


Now do you see? This is the simple case, in C++. (it should work, but i don't know much C++, there might be some pointer dereferencing needed, just PM me if theres anything wrong with it.).

This is the simple case, it uses pointer arithmatic, to do the string search.

How does it do this?
from the loop


while (index < strl) {
if (index != fto) {
*Index = &index + findlen;
*fto = &flen;
Continue;
} else {
if (&fto > &find) {
*fto = &fto--;
Continue;
};
// sucess
return &index - &string
};
};
};

So, as long the pointer for index, is smaller then the pointer for the upper bound of the string, do.
If the character at the current pointer to index is not equal to the character that fto points to (one of the characters in the find string, usually the last, exept when it gets matches).
The previous (length of find string) characters cannot be the find string, because the last character is bad.
So, move ahead (length of find string) characters and try again.

Now once you've got a match, (the else clause)
If the pointer for fto is greater then the start of the string (so we don't keep going, past the beginning of the string)
We decrement the pointer, so that it now points to the character before what it used to.
Now if the previous statement is false, then fto is exactly equal to the beginning of the find string
So we have checked the entire string, so, we have found the string and we give back its index
We calculate that by, how much larger the current intex is then the string.


From,
Nice coder

Share this post


Link to post
Share on other sites
Quote:
Original post by Extrarius at 1/2/2005 4:16:16 AM
There is also the sometimes-helpful National Institute of Standards and Technology's Dictionary of Algorithms and Data Structures
Quote:
Original post by flangazor at 1/2/2005 7:00:04 PM
Quote:
Original post by Flarelocke
Wikipedia also has a nice list.
NIST has some too.

Share this post


Link to post
Share on other sites
A hash table.

When to use it:
When you need constant time reads/writes.

When not to use it: when your dealing with a small amount of data

Psudocode:


Table() Struct for Elements in table:
Entries()
Struct for elements in entries
Pointer Entry
Integer FullHash

Function hashtableretrieve(key)
hsh = hash(key)
chsh = hsh modulo Tablesize
pointer ctable = pointer to table(chsh).entries
Find hsh, in ctable, using binary search.
Return either the entry (pointer), or falure of the search fails.

end function

function hashtableadd(key, value)
h = hashtableretrieve(key)
if h is not equal to falure then
return falure
end if

hsh = hash(key)
chsh = hsh molulo Tablesize
Pointer ctable = pointer to table(chsh).entries
Add a new element to ctable,
In that elemsnt, make Element.entry equal to value
And Fullhash equal to hsh
Sort ctable

end function

function hashtableremove(key)
hsh = hash(key)
chsh = hsh modulo Tablesize
pointer ctable = pointer to table(chsh).entries
Find hsh, in ctable, using binary search.
Remove the element in which it is found.
end function


From,
Nice coder

[Edited by - Nice Coder on January 2, 2005 11:34:52 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Nice Coder
Imalc: no offence taken. I just usually hand out psudocode that isn't as optimised. Nice code. Too.
Yeah I thought it might be just to show the principle, never mind.
Quote:


	if (a[m] < f)
l = m++;
else
r = m--; // -- needed here, to make sure that it terminates.
There's actually a big a problem with that. It's my fault I suppose, there's something I forgot to mention...
In that first if-statement the true case handles just < which means that the lower bound is definately above m (hence the +1). HOWEVER, the else case handles >=, so because that includes the equal case we include m in the range, hence it is actually correct to not be subtracting one. (Yes that's right, even the subtracting one has been cunningly optimised out!)

It will still always terminate because even though we set r to m, we know that l is less than r (loop condition), so the truncation in (l+r)/2 will round m down, hence m will always be less than the original r.
The code you posted will not work in ALL cases.

I should have said that what I posted was in fact already throughly tested and optimised, bug-free code. In fact I very much doubt an assembly version would squeeze much more performance out of it.
I can tell you didn't try the change out, by the missing semi-colons. It's quite an understandable mistake, given my lack of explanation.

My original version did have an explicit shift instead of the divide as well, but I changed it in what I posted, I don't know why really.
I didn't use ++ because there was no need to store the result back into m.
	if (a[m] < f)
l = m+1;
else
r = m; // -1 NOT needed here, It does terminate!!

Share this post


Link to post
Share on other sites
I just noticed one other thing in your hash table psuedo code:
Quote:
Find hsh, in ctable, using binary search.
Unfortunately items in a hash table aren't guaranteed to be in order, hence a binary search wouldn't always work. Or am I missing something? I did skim over it pretty quick.

Maybe someone else should post code for some interesting algorithm so it doesn't look like I'm picking on Nice Coder![smile]

Hmmm, how about a non-recursive binary tree insertion routine?
//'head' is the binary tree pointer.
//'ins' is caller allocated and already contains the data to be inserted.
//operator < must be overloaded.
template <class TNode>
void TreeInsert(TNode *&head, TNode *ins) {
TNode *curr = head;
ins->left = ins->right = NULL;
if (head == NULL) {
head = ins;
} else do {
if (*ins < *curr) {
//it goes somewhere in the left sub-tree
if (curr->left == NULL) {
curr->left = ins;
break;
}
curr = curr->left;
} else {
//it goes somewhere in the right sub-tree
if (curr->right == NULL) {
curr->right = ins;
break;
}
curr = curr->right;
}
} while (true);
}
This is actually another extract from my sorting demo program (part of tree-sort) I plan to release the full code eventually, just not yet.

Share this post


Link to post
Share on other sites
Nice imalc.

Yeah i didn't test it... (without the --)

:)

I've been thinking about an o(n) sorting algorithm. i might pm you about it later. I'm horrendus at finding faults in my own ideas.

From,
Nice coder

Share this post


Link to post
Share on other sites
Quote:
Original post by Nice Coder
A hash table.

When to use it:
When you need constant time reads/writes.

When not to use it: when your dealing with a small amount of data

Psudocode:


Table() Struct for Elements in table:
Entries()
Struct for elements in entries
Pointer Entry
Integer FullHash

Function hashtableretrieve(key)
hsh = hash(key)
chsh = hsh modulo Tablesize
pointer ctable = pointer to table(chsh).entries
Find hsh, in ctable, using binary search.
Return either the entry (pointer), or falure of the search fails.

end function
You're confused. The hash won't be unique to the element. In fact, hsh = hsh modulo Tablesize for all sensible hash functions (one of which, is in fact modulo). When the hashes collide, you search for key, rather than its hash.

And using binary search is overkill. The most important part is that it imposes an additional constraint on the keys (that they be ordered), but it also requires your addition function to insert in order. If your table's generating enough collisions to make such a thing worth implementing, it's broken.

Share this post


Link to post
Share on other sites
it takes the hsh modulo the tablesize, and then oges through the array to find the full hash. this makes it work for things that don't collide, but with only a key, its a little hard to get it to do more then that.

From,
Nice coder

Share this post


Link to post
Share on other sites
A memory manager.

Resons for use: It stops system allocations/deallocations.

Psudocode:

Function Acessor(Pointer Memory, Id)
Check Records for all memory ID can acess
If id cannot acess Memory, return falure
return Memory
end function

Function Allocate(int Howmany, id)
Find a spot where there are Howmany items Free.
If there are not, then call reallocate until there is.
Mark each of those elements as belonging to ID
Return a pointer to the memory
end function

Function Deallocate(Pointer Memory, int howmany, iD)
If memory cannot be acessed using id ID then return falure
Start at Memory, and continue until you have reached howmany
Mark the memory as free
Clear the memory
end function

Function DeallocateID(id)
For each piece of memory ID has
Deallocate it
End function


From,
Nice coder

Share this post


Link to post
Share on other sites
A really fast ABS function, for ints.

For use anywhere.


inline int16ABS(int* x) {return (x & 0x7FFF);}
inline int32ABS(int* x) {return (x & 0x7FFFFFFF);}
inline int64ABS(int* x) {return (x & 0x7FFFFFFFFFFFFFFF);}
inline float24abs(Void* x) {Return (*(int * x) & 0x7FFFFF);}
inline float64abs(Void* x) {Return (*(int * x) & 0x7FFFFFFFFFFFFFFFF);}


Those should work well.
Works by resetting the sign bit to 0. Not sure if the pointer conversion in the floats works tho.

From,
Nice coder

Share this post


Link to post
Share on other sites
NiceCoder: these do not work well. Why does bitwise-and'ing a pointer to an integer with 0x7(F*) return the abs of the integer being pointed to?

Not to mention, removing the sign bit on negative numbers that are represented as two's complement (which happens on most computers I know of) will not return the opposite of these numbers: for instance, applied to -1 ( which is 0xFFFF, not 0x8001 ), your method would return (0x7FFF) = 32767...

In the special case where negative integers are represented as two's complement, AND right-shifting fills the new bits with '1' if the leftmost bit was '1' prior to the shift, then this works:

abs(i) = i - ((i+i) & (i>>31))

Share this post


Link to post
Share on other sites

This topic is 4680 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Forum Statistics

    • Total Topics
      628718
    • Total Posts
      2984375
  • Similar Content

    • By Apollo Cabrera
      Energy particles being harnessed by collection multi-hedron energy matrix. Whuuuttt?
      Love it :)
    • By AndySv
        Total Music Collection (http://u3d.as/Pxo)   THE COLLECTION CONTAINS:   Mega Game Music Collection   Universal Music Collection   Huge library of high quality music for any project! All at an incredibly low price!   - 2,5GB of high quality audio - 100+ different music tracks - Loop and short versions   Action, fantasy, casual, horror, puzzle, epic, dramatic, romantic, positive, inspiring, motivational and more!
    • By Dafu
      FES Retro Game Framework is now available on the Unity Asset Store for your kind consideration!
      FES was born when I set out to start a retro pixel game project. I was looking around for an engine to try next. I tried a number of things, from GameMaker, to Fantasy Consoles, to MonoGame and Godot and then ended up back at Unity. Unity is just unbeatable in it's cross-platform support, and ease of deployment, but it sure as heck gets in the way of proper retro pixel games!
      So I poured over the Unity pipeline and found the lowest levels I could tie into and bring up a new retro game engine inside of Unity, but with a completely different source-code-only, classic game-loop retro blitting and bleeping API. Months of polishing and tweaking later I ended up with FES.
      Some FES features:
      Pixel perfect rendering RGB and Indexed color mode, with palette swapping support Primitive shape rendering, lines, rectangles, ellipses, pixels Multi-layered tilemaps with TMX file support Offscreen rendering Text rendering, with text alignment, overflow settings, and custom pixel font support Clipping Sound and Music APIs Simplified Input handling Wide pixel support (think Atari 2600) Post processing and transition effects, such as scanlines, screen wipes, screen shake, fade, pixelate and more Deploy to all Unity supported platforms I've put in lots of hours into a very detail documentation, you can flip through it here to get an better glimpse at the features and general overview: http://www.pixeltrollgames.com/fes/docs/index.html
      FES is carefully designed and well optimized (see live stress test demo below). Internally it uses batching, it chunks tilemaps, is careful about memory allocations, and tries to be smart about any heavy operations.
      Please have a quick look at the screenshots and live demos below and let me know what you think! I'd love to hear some opinions, feedback and questions!
      I hope I've tickled your retro feels!



      More images at: https://imgur.com/a/LFMAc
      Live demo feature reel: https://simmer.io/@Dafu/fes
      Live blitting stress test: https://simmer.io/@Dafu/fes-drawstress
      Unity Asset Store: https://www.assetstore.unity3d.com/#!/content/102064

      View full story
    • By Dafu
      FES Retro Game Framework is now available on the Unity Asset Store for your kind consideration!
      FES was born when I set out to start a retro pixel game project. I was looking around for an engine to try next. I tried a number of things, from GameMaker, to Fantasy Consoles, to MonoGame and Godot and then ended up back at Unity. Unity is just unbeatable in it's cross-platform support, and ease of deployment, but it sure as heck gets in the way of proper retro pixel games!
      So I poured over the Unity pipeline and found the lowest levels I could tie into and bring up a new retro game engine inside of Unity, but with a completely different source-code-only, classic game-loop retro blitting and bleeping API. Months of polishing and tweaking later I ended up with FES.
      Some FES features:
      Pixel perfect rendering RGB and Indexed color mode, with palette swapping support Primitive shape rendering, lines, rectangles, ellipses, pixels Multi-layered tilemaps with TMX file support Offscreen rendering Text rendering, with text alignment, overflow settings, and custom pixel font support Clipping Sound and Music APIs Simplified Input handling Wide pixel support (think Atari 2600) Post processing and transition effects, such as scanlines, screen wipes, screen shake, fade, pixelate and more Deploy to all Unity supported platforms I've put in lots of hours into a very detail documentation, you can flip through it here to get an better glimpse at the features and general overview: http://www.pixeltrollgames.com/fes/docs/index.html
      FES is carefully designed and well optimized (see live stress test demo below). Internally it uses batching, it chunks tilemaps, is careful about memory allocations, and tries to be smart about any heavy operations.
      Please have a quick look at the screenshots and live demos below and let me know what you think! I'd love to hear some opinions, feedback and questions!
      I hope I've tickled your retro feels!



      More images at: https://imgur.com/a/LFMAc
      Live demo feature reel: https://simmer.io/@Dafu/fes
      Live blitting stress test: https://simmer.io/@Dafu/fes-drawstress
      Unity Asset Store: https://www.assetstore.unity3d.com/#!/content/102064
    • By Dafu
      Hello all,
      I've been hard at work on a new retro pixel-perfect framework called FES Retro Game Framework. It is now available on the Unity Asset Store for your kind consideration!
      FES was born when I set out to start a retro pixel game project. I was looking around for an engine to try next. I tried a number of things, from GameMaker, to Fantasy Consoles, to MonoGame and Godot and then ended up back at Unity. Unity is just unbeatable in it's cross-platform support, and ease of deployment, but it sure as heck gets in the way of proper retro pixel games!
      So I poured over the Unity pipeline and found the lowest levels I could tie into and bring up a new retro game engine inside of Unity, but with a completely different source-code-only, classic game-loop retro blitting and bleeping API. Months of polishing and tweaking later I ended up with FES.
      Some FES features:
      Pixel perfect rendering RGB and Indexed color mode, with palette swapping support Primitive shape rendering, lines, rectangles, ellipses, pixels Multi-layered tilemaps with TMX file support Offscreen rendering Text rendering, with text alignment, overflow settings, and custom pixel font support Clipping Sound and Music APIs Simplified Input handling Wide pixel support (think Atari 2600) Post processing and transition effects, such as scanlines, screen wipes, screen shake, fade, pixelate and more Deploy to all Unity supported platforms I've put in lots of hours into a very detail documentation, you can flip through it here to get an better glimpse at the features and general overview: http://www.pixeltrollgames.com/fes/docs/index.html
      FES is carefully designed and well optimized (see live stress test demo below). Internally it uses batching, it chunks tilemaps, is careful about memory allocations, and tries to be smart about any heavy operations.
      Please have a quick look at the screenshots and live demos below and let me know what you think! I'd love to hear some opinions, feedback and questions!
      I hope I've tickled your retro feels!



      More images at: https://imgur.com/a/LFMAc
      Live demo feature reel: https://simmer.io/@Dafu/fes
      Live blitting stress test: https://simmer.io/@Dafu/fes-drawstress
      My own game I started working on using FES, a roguelike, very early: https://simmer.io/@Dafu/merl
      Unity Asset Store: https://www.assetstore.unity3d.com/#!/content/102064
       
       
  • Popular Now