I'm here at the MAGFest 2016 LAN Room.
It's one of the largest LANs on the east coast, and as I'll probably show in another video,
about the most ridiculous network system you'll ever see.
Right here, though is a little tiny ESP8266.
Let's see if we can get it to focus.
Right there.
And, unfortunately, it doesn't have a regular framebuffer output on.
You know, unless you use channel 3 which is just an awful solution.
But, if you want something better, it can actually serve up VNC.
This is using that age old technology VNC to tell the client here what to render.
And, as you can see it's actually kinda in 3D so if you jump, you can actually see that
it's a bunch of bullets, a bunch of other players and a bunch of plyons.
This game is called pylotron, it's available on github.
The link is in the description.
And, the general goal is destroy all of the pylons, which you get points for and kill
all of the other players.
So, as you kill players you can accumulate 100 points.
By killing a pylon you get 50 and if you die you lose 100 points.
So, it's uuh a very fast paced game where you have a bunch of players who are trying
to kill each other in order to keep moving.
Now, this entire game actually runs on the ESP8266 and its communicating using Render
Frame Buffer, the same thing that's used in VNC in order to tell the clients how to render.
I'll probably go into that a little bit later.
Right now, let's just see what happens as he starts killing some more of these things
here.
Whoop he's almost dead there.
Uuh.
Nooo don't die.
Uh Aahh.
Ok, so he just killed player red.
Let's see this is yellow here.
There's only a few pylons left.
Oh one of the other interesting things, here is the high score screen, it happens at the
end of the game and shows you all of the different scores, deaths all of that are.
Right here, hooked up to the ESP8266 is a strip of WS2812 LEDs, these show the high
score ranking of who's in first, second, third, fourth, and etc.
Admittedly developing this directly on an ESP8266 would be quite the daunting task,
so, instead I decided to develop it on my Linux computer.
You may say "oh, how do you just transfer it?"
Well, it's the matter of interfaces.
Because right now, there is an interface file, I can develop on Linux but then port it very
easily.
When I say interfaces what I mean is the same sort of thing as when I ported Minecraft to
an AVR.
Instead of trying to use berkley sockets, which are terrible for trying to keep things
small, instead I have some really basic functions like "is there data waiting for this client?"
"Can I start to send a packet for this client?"
"Send some data to the currently open sending connection" "Send 1 byte" "2 bytes" "4 bytes"
4 bytes meaning like a uint32.
Or, once we're done, send an end send.
This kind of interface makes it really easy to have a server where you can have all of
these different features where you can have reading, writing to sockets and you can do
so in a way that in this case you have a file that makes it compatible with Linux, or in
the case of the ESP, we can have another file that makes it compatible with the ESP.
So, here in user_main, we have the same sorts of functions.
So here, StartSend, SendData, Send1, Send2, Send4.
Because this code exists both for Linux and for the ESP, as far as the game development
and render framebuffer development was concerned, beacuse I had to write all the functions to
display all the things to the clients, it was a lot easier to write it in Linux, where
I could say make clean all.
Boom.
Run the server on Linux instead of having to program and retest the ESP.
This is really a testament to how interfaces can help in this situation.
This here is the font I used for the pylotron game on the ESP8266.
Unlike most projects where you would store a font in the actual data.
All of the pixels here would be stored in the game.
In order to conserve space on the wire we use something called RRE, which is basically
a series of rectangles we want the client to draw.
For instance if we want to draw "H" instead of having to store all of these pixels and
all of these bits, we can store them as rectangles.
So, this.
Boom.
This Boom. and This are all you actually need to draw an H. Now granted some of the other
letters are a little more complicated to get, it still saves a lot of space just to be able
to store the shapes that the letters make.
This is done by using a fonter.
This file here opens up this image and figures out what shapes to draw over the objects in
order to make them all fit.
So for this this geometry right here, we can see that the total places, the total number
of pieces needed to represent it is actually only 1564.
So for all of these characters here, I believe it's all 256 yeah 256 letters, only 1564 rectangles
are actually used.
So, in my book that's a pretty good compression ration.
This here is the main FPS file, fps.c.
So, this contains all of the logic for all of the players their points, the everything
including the rendering.
Unlike normally, when you use VNC, you would normally connect to another person's computer
and see their desktop.
That means it's just transferring over the network an image of their desktop, unlike
here we're using it simply to push geometry.
The ESP has no recolletion of what someone has on their screen.
It doesn't render it it doesn't care because it can push it to their screen and be done.
So the way the ESP does this is it iterates through all of the things that might be displayed
that includes the players and the pylons and the bullets the players might be shooting,
and it renders them into this list of objects.
And that actually goes into a heap.
So, a heap is a data structure that allows us to store data and when we're done, pull
it out in a specific direction.
That's really important for later.
We start drawing a frame, and that's that it says let's clear get ready to go.
If you just got hit, we want to turn the sky red, so you get that viceral guaahh I just
got hit feeling, or just blue if it's normal.
And so 7 in this case means red, and 8 in this case means blueish not quite bright blue,
but regular blue, and if nothing's going on just green.
So, real simple.
Colors.
Green for the ground blue for the sky.
And it matters that you draw them in this order.
Let's open up a copy of the game here.
So, we're actually going to draw here, the sky is blue, the ground is green.
And I can kinda walk around here and shoot things.
Let's see.
Entere.
There it is.
So I'm shooting these balls and they're hitting things.
And I'm shooting that pylon.
We can see that that pylon is green and we can see that other pylons will get infront
of it or behind it and see how it would be.
So, that's all done by drawing the pylons storing them in this heap, and then drawing
everything in the scene from the back, things that are way back there, let's shoot that
so we can get an inkling there.
Drawing that all the way forward.
That way when we want to draw the scene, the objects in the foreground are drawn in front
of the objects in the background.
If we were to draw it in the opposite order we'd be able to see straight through the objects
in the foreground to the objects in the background, so we render all those things, we store them
up then we send them to the client.
So, we check that the object is visible, because if we spin around we can't see the object
there.
So the green one is behind us, and we don't want to send that to the client, instead we
only want to see objects that are visible.
And, we draw that, it's just a block.
We send that to the client.
Last thing we draw on the screen here, main part of the screen is the little red dot in
the middle it's done by telling the client to draw a square.
And, right here, if the game is over, aww, it stops there.
If the game is not over there or however we are rendering it here, then, what we end up
doing is we'll end up drawing on the bottom this text.
So we actually only draw one thing at a time every frame, otherwise we'd spend too much
time sending data to the client and it's really critical on the ESP to minimize the amount
of data we're sending to the clients.
So, for the first frame, we're sending just the health.
For the next frame we're sending the player's points, right there.
Next frame, kills, deaths, bullets, pylons remaining, so... kills, deaths, bullets, pylons
remaining.
So, I'm just gonna kill this pylon here, you can see it getting smaller, smaller smaller
and now it doesn't exist anymore.
And that's how we actually push all these 3D graphics to the player.
Theres actually a little bit of magic going on here to determine the positions and the
sizes, because objects in the distance have to be smaller than objects in the foreground.
Some of that's using these really cute tables, so TATAN2, I actually forgot what file that's
in.
So, in here, we have basic mathematical functions.
Sin's and Tangent's, these take advantage of tables, so rather than doing some magical
transindental function for sin which is really hard and all that, we can look up in table
right here and just get a value out.
So, that's why it's a little bit jankey when you're playing the game.
Let's go back here.
So, if I'm turning you can see the objects lirching a little bit, and not really smoothly
going that's a function of the TAN function and the SIN function being terrible.
Instead of having a nice smooth output, we have chunky, moing from 0 to 6 and so on output.
So it makes the data a little bit worse but at the same time it's a really small table
and makes things go really fast and the ESP absolutely adores that.
In addition we can do all of these things on Linux to make sure everything's working
before we move it off to the the ESP for actual game.
So, that's I guess kinda a crash course on how all that goes together.
If you wanted to make a game like this on the ESP, you could totally modify this FPS.c
file here and change the rules, change the behaviors and still have any kind of first
person shooter you want SO LONG as all of the objects in that first person shooter are
made out of squares.
I hope you liked this video and associated explaination.
If you can, just comment give me a heads up, what you'd like to see more of and I'll try
to keep making these videos.
Thanks for watching.