CubicRealms

Play Online (Java applet)

This is my latest project! A JavaScript toy I made called Worldpaint was more popular than I expected, so now I’m developing it into a full game. I’m going to add multiplayer and finish sandbox mode, then most likely add some additional features like deathmatch (similar to Worms) and CTF.

When you open the game it generates a level (512 x 512 blocks). Look underground for some caves! Use the mouse to create and destroy blocks; there are 3 layers you can build on: in front of, behind, and on the same level as your character.

Ladders and water are automatically placed on layer 1 (behind you).

Controls:
A, D - move
Space - jump
Q, W, E - change layers (the indicator at the top left shows your current layer)
Left click - place block (must be touching an existing block)
Right click - destroy block

Water flows realistically; the last block is a waterfall that was used for testing dynamic water, and will probably be removed in the final game.

Much of my inspiration came from Minecraft; the original Worldpaint was partially based on PlayPen.

Known bugs:
-If you place a lot of moving water, it will start to behave erratically and cause low FPS. This is difficult to do unless you use the waterfall block.
-The level generator is a bit wild, you can get huge mountains and caverns that are dozens of blocks tall. Not sure whether this is good or bad.
-Depending on the topography of the level and the number of cave waterfalls, there can sometimes be a large amount of block changes after you first load the game, causing poor performance. If you wait a minute or two it will improve.

Made a lot of progress on MP today (PyroNet is cool, last time I used MINA I promised I never would again):

Might host a test server tomorrow or the next day.

As the author of PyroNet, let me say this:

IO is often faster than NIO. NIO uses less threads, and thus less RAM, but you can set the stacksize of a thread then creating it (minimum seems to be 48K). In the end, there are very few situations where you need NIO. When using NIO, all your I/O code has to be async, meaning: lots of callsbacks and lots of bugs.

Now if you do the math, and you use 48K-stack threads, you can fit ~2750 threads in 128MB. For a server 128MB is nothing, and 2750 threads (and thus 2750 connections, or players) with all their game-logic, will quickly saturate the CPU (or RAM, or disk I/O) of your server anyway.

You should be very certain you actually need NIO (and thus PyroNet). You’re very likely to make it very hard for yourself, for no gain at all. I, for one, have only 1 application that uses my own PyroNet (a datamining cluster). All my other projects (among which an http server that blasts out 1200 tiny javascripts / second, all on their own tcp connection) use the standard classes in java.io and java.net: it’s faster (seriously), it’s easier to write, debug and maintain. And the code actually makes sense to you, two weeks later.

Do yourself a favor and do not use PyroNet for your project :slight_smile:

No luck running here . The applet loads, then it remains blank .

The console just shows

3
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23

I read somewhere that NIO is good if you have a small number of clients sending/receiving a large amount of data each, is that correct?

Callbacks and threading issues were one of the many factors that killed my last project, so if needed I could probably switch to plain IO.

@teletubo, what OS are you on? (the numbers mean it is generating the level, so it must be a display problem)

NIO has the advantage, that if you only use direct ByteBuffers, it is, in theory, zero-copy. In reality, you’re probably going to copy the bytes a few times anyway (otherwise you have to do your own memory management like in C) and methods like ByteBuffer.compact() do copy data around too. I think it’s a fair guesstimate to say your data gets copied about 3-5 times before it ends up in your engine in java objects. Whether you have 1 more copy due to IO (as opposed to NIO) doesn’t really matter. It is highly unlikely that network I/O will saturate your memory I/O anyway.

So unless you have things like a NAS with dozens of harddisks in RAID, and you’re building a fileserver connecting to it, it really doesn’t matter. If your network I/O is factor 10 slower than it currently is, you probably won’t even notice it.

I won’t worry about it for now, there’s no lag at all unless you do something stupid like having 2,000 water blocks all moving at once.

I was able to reproduce the graphics/sound bug on my Mac, so it should be fixed now (not sure about Linux though).

Also tweaked the physics a bit.

I have a test multiplayer server up right now, go here: http://1scripts.net/cubic/multiplayer.php

You have to sign up, but feel free to use a fake email address.

The applet loads up, I hear the sounds but all I see is a black screen, the console shows packets sending so it seems to be running but idk. I am on windows 7 64 bit, with 1.6.0_19 java console…if that helps.

Mac people have this issue too, not sure about the cause. I just asked about it here.

Hey Jacob_, I just launched the game and it worked, I dont know if you changed anything but its working now ??? ;D.

Yeah, I decided to try using a JApplet with graphics drawn on a JPanel. Glad it works!

Also, to the people who say/think it is a Minecraft “ripoff”, keep in mind that although it was partly inspired by MC, the final game is going to be more like Worms with building. Following that logic, Minecraft is a “ripoff” of Infiniminer. :stuck_out_tongue:

I just released a small update, it fixes some bugs/things that were counter intuitive.

-Water and ladders are now placed on layer 2, not layer 1, this means you can put them in front of things.
-Fixed a bug where walking sounds would play when you weren’t moving
-Fixed bugs with save/load
-Saving/loading no longer works in multiplayer
-Added sounds for walking on dirt

Here is a tower that was built on the test server yesterday:

Once I get more people to play the game I might release the server software.

Server software is public now, you can download it from the site.

I also added a server browser to the client.

Small update is out: http://1scripts.net/cubic/game.php

I fixed some more bugs and added some new sounds. (The grass walking sounds really needs some more work, I’m terrible at audio stuff!)

Also, if the game crashes it will now tell you what the error was, in case you want to tell me.

I started working on realistic lighting, but it’s still buggy so I disabled it for now. It’s definitely better than the irremovable shadows you see underground currently.

By the way, this doesn’t suck like the last game I posted :slight_smile: The few people that have tried it said they liked it, and most built some cool stuff in multiplayer.

hey,
Single player version works fine, however when I tried the multiplayer one, I selected the first server, then It said “Welcome to server A”, after a while the game appeared, and almost immediatelly appeared “Welcom to server B”, then crashed …



http://1scripts.net/cubic/getSkinURL.php?n=Guest4875
[2010-07-21 00:58:52] Unknown command: -105
jawnae.pyronet.PyroException: call from outside the network-thread, you must schedule tasks
	at jawnae.pyronet.PyroSelector.checkThread(PyroSelector.java:107)
	at jawnae.pyronet.PyroClient.dropConnection(PyroClient.java:350)
	at com.mynet.cubicrealms.net.Connector.disconnect(Connector.java:87)
	at com.mynet.cubicrealms.net.Connector.handlePacket(Connector.java:286)
	at com.mynet.cubicrealms.net.Connector.processData(Connector.java:119)
	at com.mynet.cubicrealms.net.ClientListener.receivedData(ClientListener.java:47)
	at jawnae.pyronet.PyroClient.onReadyToRead(PyroClient.java:459)
	at jawnae.pyronet.PyroClient.onInterestOp(PyroClient.java:408)
	at jawnae.pyronet.PyroSelector.handleSelectedKeys(PyroSelector.java:244)
	at jawnae.pyronet.PyroSelector.select(PyroSelector.java:173)
	at com.mynet.cubicrealms.net.Connector.run(Connector.java:82)
	at java.lang.Thread.run(Unknown Source)


According to the stacktrace, the network thread seems to be reset between PyroClient.onReadyToRead() and PyroClient.dropConnection()

Jacob, do you call PyroSelector.spawnNetworkThread() ? Is so, it should be only called once and in the beginning of your application, before any PyroSelector.select() calls.

The problem was that I accidentally tried to drop the connection on another thread (without using Selector.scheduleTask()). So when the client tried to disconnect, the game crashed.

The invalid command part bothers me though, looks like something is wrong with the packet reassembling code. I added some extra debugging stuff, can you try it again?

Edit: Actually, now that I think about it, disconnect() is being called in the same thread as the other network stuff in this case.

Connector.java:line 286 is the code that disconnects the client if it receives a kick packet, which shouldn’t happen normally. Based on the fact that you saw 2 welcome messages, and the unknown command, something is getting messed up somewhere, causing the rest of the buffer to be read as random commands.

I know this isn’t a help thread, but does anyone spot an obvious error in this code?

    public void processData(ByteBuffer buf)
    {
        ByteBuffer readbuf = ByteBuffer.allocate(1048576);
        if(unfinished.position() != 0) //unfinished is a field
        {
            unfinished.flip();
            readbuf.put(unfinished); //If there was a message fragment in the last packet, append it to this one
        }
        unfinished.clear();
        readbuf.put(buf);
        readbuf.flip();
        while(readbuf.remaining() > 0)
        {
            int cmd = readbuf.get();
            int size = Packet.getSize(cmd); //Returns packet size for this command (including the command byte)
            if(readbuf.remaining() >= size - 1) //If there is a complete packet, process it
            {
                handlePacket(cmd, readbuf);
            }
            else
            {
                unfinished.put((byte) cmd); //If not, add the fragment to the incomplete packet buffer
                while(readbuf.remaining() > 0)
                    unfinished.put(readbuf.get());
            }
        }
    }

haha,really great game :). I built a two story house up a ladder a bit, hahaha.

Thanks :slight_smile:
Here’s a preview of the new realistic lighting:

Still needs some work, as you can see the light doesn’t dissipate in the ground fast enough. Blocks were supposed to block light, but I couldn’t figure out an algorithm that was fast enough.

I’m going to improve it some more (maybe add night/day!), then hopefully try to fix up the sounds.