Fenrock (Mark) has released an early prototype of what will become one of the most amazing FujiNet networking demo for 8-bits ever (my personal prediction).
In the video above, a virtual Atari (Altirra) is on the left, a real Atari on the right. Both are connected to a bouncy_server using FujiNets and running Mark’s bouncy client. The server takes care of all object movement and collisions, it sends down coordinates for the clients to simply paint the bouncies at the proper x/y location and to shave off parts as they move across boundaries. Mark has more features to control the setup of the screens planned as well as multi-client support for incredible demos.
Fenrock gave a quick rundown of where is currently is in terms of development of Bouncy World:
fenrock: Quick rundown of bouncy world client
Good stuff
- works over multiple clients I need to work out how to run multiple altirras and multiple fujinet-pcs to demo more clients
- there’s minimal things that need implementing per client, just converting chars to printable strings for the platform
- it’s a pretty simple basic cc65 app so easy to adapt
Bad stuff
- real hardware Atari FN is running out of heap, need to track down why. [This was quickly fixed]
- the graphics printing is extremely primitive, just clears the screen before printing all the shapes on the client, so it “flashes” quite a bit. Need some double buffering and faster drawing as it’s all goto xy / cputc at the moment.
- only implemented Atari at the moment, but I’ll do an Apple client next
It turns out the way I had chosen to open a stream to client and pump data from the service didn’t work as I expected, so I think I didn’t need to have the 2 channel N1: and N2: stuff I wrote for apple after all, but I did it and it’s there if people need it.
Fenrock is planning to follow up with C64 and Apple2 clients which will allow them to join the Bouncy World.
Bouncy Q&A
A Question and Answer session between an Apple2 Dev and fenrock on Discord
Edited for clarity and consistency
Q: What is Bouncy exactly? I’ve looked at your recent Bouncy test. I am – once more – afraid that I don’t understand the scenario / use case, but it seems interesting.
A: fenrock: Thanks! The use case / setup is:
- It’s just a big demo of cross platform fujinet-lib (network) data reading
- there is a world with body objects in it, of various sizes, 1×1, 2×2, 3×3, 5×5
- each body has a direction, speed, and mass
- they bounce around in the world off each other, and currently wrap at the edges – but I will make that configurable to bounce instead off the world boundary edges instead of wrapping to the other side of the world
- the code for the world is a Kotlin application with a rest controller and endpoints for clients to connect, and get the body objects within their viewport
When a client registers it causes the world total size to grow, so 2 clients don’t overlap.
Clients simply register, download the shapes of objects, then have a main loop to get all the bodies in their viewport.
The server sends very small amount of data, just shape ids and their x,y coordinates translated to the client’s screen size (which the client sends as part of the registration).
Clients are completely free to interpret the shape data how they want, it’s sent as NxN chars (eg 25 chars for 5×5 body) which the client can paint how they want, I used atascii chars for Atari, but graphical blocks and colours are equally good and would look super cool as shapes move across screens
The client is incredibly dumb, all it has to do is paint the shapes at the coordinates it is given. All physics, bouncing, etc is done by the server, it was way too much for the client to handle, so there’s a central service that runs the simulation, clients just constantly ask for what they can see, and the server calculates for each body every client that can see any part of the object (including partial views due to overlap), which gives the illusion of them passing between screens, obviously
Q: What made you want to create this demo?
A: (fenrock) The idea behind bouncy-world was something we discussed at VCFE, we were looking at the “rock paper scissors” graphical demo for the c64 (see https://csdb.dk/release/?id=231377 – it’s a graphical screen with icons that bounce around).
I’d been trying to think of a demo we could do between different FujiNets at the show (they are usually lined up in a row on the desk).
I’d previously seen many many years ago a bird flying between 2 BBC Archimedes machines that were plugged together to communicate where the “bird” was, and I thought a multi-client asteroids type application would be a good demo, where things would move between the screens like the birds did in the BBC demo.
It could be written in fujinet-lib as a cross platform application. JeffP was very keen to see something like this for a VCF show.
A couple of months ago, I started writing the server side. I had originally thought it to be client to client driven, but very quickly realized that would be a nightmare to write, so went with a central controller model, a single simulation (which I’ve written plenty of over last couple of years), with clients acting as visual portals into the simulated world.
So that’s the background for it all. We wanted stuff to show off at VCF.
Q: Thanks for the comprehensive background. You write “download the shapes of objects” and then “clients are completely free to interpret the shape data how they want”. Does that mean you have some machine-independent “shape description language”? Maybe SVG?
A: Ha, it’s just ascii chars, that pseudo represent what I’m trying to convey:
I add the shapes to the server like this:
shapes.addAll(listOf(
createShape(4.8f, fromString(
"""
| ┬┬
|└┤├┼┤
| ┼ ┼
|┌┤ ├┤
| ┼┴┴
""".trimMargin()
)
),
but the fromString method converts them to simple ascii here: https://github.com/markjfisher/bounce-world/blob/master/src/main/kotlin/data/ShapeCreator.kt#L16
e.g.
‘┌’ -> ‘r’.code
‘┐’ -> ‘)’.code
‘└’ -> ‘L’.code
‘┘’ -> ‘!’.code
‘┤’ -> ‘J’.code
‘├’ -> ‘t’.code
The “display” routines in the host are simple character prints at the moment, but it could do graphics instead.
for (i = 0; i < width; ++i) {
y = startY + i;
firstXInRow = false; // Reset for each row
// Only proceed if the row is within the vertical screen bounds
if (y >= 0 && y < SCREEN_HEIGHT) {
for (j = 0; j < width; ++j) {
x = startX + j;
// Check if the current character is within the horizontal screen bounds
if (x >= 0 && x < SCREEN_WIDTH) {
if (!firstXInRow) {
firstXInRow = true; // Found the first x position in this row within bounds
gotoxy(x, y);
}
cputc(data[i * width + j]); // Print and move to the next position
} else if (firstXInRow) {
// If we were printing characters and have now gone out of bounds, break
break;
}
}
}
}
You can see it’s just getting to the right row/column, then printing the chars with cputc() But graphics blocks are possible too.
The Future
The possibilities for this client server system are pretty open, I myself (Andy) am very excited to see where this takes off to and what comes out of it. Commodore 64 has a lot of character based blocks and shapes, Apple2 has the mouseText in most IIe and IIc so some interesting cross-platform bouncies can be created for this first version.