r/java • • 5d ago

Using Java skills for something a little different

Post image

Java is quite a handy language. Though it's challenging to use it for more fun projects. Towards that end, I set myself a challenge to use Java to build a browser-based game. No server, no API, just pure Web Assembly driven game play. Yes, there's some JavaScript glue, because, well, you gotta, but, the core logic is all Java. Along the way I learned that streams allocate a lot of objects, so I switched back to good old for loops... And watched the GC usage drop a fair bit. What I really do enjoy is how Java has evolved and changed over the years, and it makes it a lot simpler to do things like this. Records save me a ton of boilerplate code. Playable at https://nofuss.co.za/games/wartech/, but it's a bit meh on mobile, I'm still working on that. My focus right now is desktop play, and getting sound to work. Flame me in the comments with bug reports, I know there's a few... Hundred.

UPDATE: As promised, it's now open-source at https://github.com/ewaldhorn/wartech

195 Upvotes

46 comments sorted by

23

u/-Dargs 5d ago

Streams allocate tons of objects, yep. Short lived anonymous classes. At work we switched over to using streams pretty aggressively without really benchmarking and didn't notice just how much resources were burned away. It took some time, but we eventually migrated back to using good old for-loops almost everywhere (in non-batch process code).

5

u/According-Ad-7069 5d ago

Oh definitely. For work, on short-lived instances, streams are easier to reason about, sometimes, so we mix and matched, but for loops are still my default. Mostly I need to use streams for interviews these days!

3

u/pron98 5d ago

What was the performance impact of these allocations and what GC and JDK version did you use?

6

u/-Dargs 5d ago

More heap memory, longer and more frequent GCs. At the time I think it was ZGC on j24. We were seeing full pause GCs for like 50ms every 2 minutes. Very high throughput (typically) low latency systems. It wasn't a good situation.

2

u/zabby39103 4d ago

I found this too a few years ago, the difference was actually quite large, i think more than 2x... for a hot path loop case, with nested loops inside.

Most things aren't hot path loops going through 200k-500k iterations, but for those that are, streams are not good. Although sometimes you can multithread your way out of it with the streams stuff, and I believe newer java versions help, for us it was Java 8.

9

u/doobiesteintortoise 5d ago

Pffft. I played it; it's a little confusing the first time in figuring out how things work and where things can go, but ... I mean, what the heck, this is cool and well done.

5

u/According-Ad-7069 5d ago

Yes you are so right, it's super confusing right now. I'm working on a tutorial, with some intro missions to help you figure things out. This comment bumps that requirements higher on my list, thank you.

17

u/sunk-capital 5d ago

The UI is all claude yeah? Not witch hunting just there is something about it that screams AI

12

u/According-Ad-7069 5d ago

The CSS had a huge Gemini contribution. As an API developer, you really don't want to see my CSS... Basically, I get it on the screen and then I say: "Make this look nice. Make no mistakes". It makes mistakes, but less than I would...

7

u/Prozilla6 5d ago

This might be controversial, but I would have preferred seeing your own UI. I believe it would have a lot more personality and uniqueness than this.

8

u/According-Ad-7069 5d ago

Totally agree with you, I just need to learn a bit about how to do it and I will rework it and make it hideous haha. Just kidding, give me a few weeks to find time to learn some things.

7

u/realqmaster 5d ago

As someone who grew up with Dune 2, this gives memories. Really cool!

3

u/According-Ad-7069 5d ago

Oh you are way too kind - Dune 2 was the GOAT!

2

u/agentoutlier 5d ago

Yeah I was hoping to have my son experience Dune 2 but could not find my ancient copy and it is not on steam.

So I tried Dune Spice Wars and holy fuck that game is overcomplicated.

Age of Empires is available and my son loves that game but its a shame Dune 2 is not.

This is the same with a lot of old games like Simcity, Civilization etc. The new versions are just too complicated.

2

u/According-Ad-7069 5d ago

You might want to look at https://dune2.hypn.za.net/ ... Just saying.

2

u/agentoutlier 5d ago

Well there goes my evening...

2

u/According-Ad-7069 5d ago

Delighted to help! I've burned a few hours on it...

6

u/PlasmaFarmer 5d ago

Always happy to see someone doing the same hobby as me, doing games in Java. Mandatory JMonkeyEngine mention, check it out for games.

1

u/According-Ad-7069 5d ago

JMonkeyEngine is so awesome! I have played with it quite a bit, used to do desktop Swing apps so it was a good fit. They haven't added Web Assembly support yet have they? I wonder how hard that'll be, with TeaVM and even GraalVM able to target wasm32 now.

1

u/msx 5d ago

Me too, although I'm more of a libgdx guy. Ps there's /r/javagamedev for us!

5

u/msx 5d ago

Looking forward to trying it tomorrow morning! Ps post it on /r/javagamedev too if you want :)

1

u/According-Ad-7069 5d ago

Oh that's a great idea thanks! I'm busy cleaning up my incredibly messy code (didn't think anyone would ever see it, the comments are atrocious), but when it's clean in a day or two, with some docs on how to build it, I will post it there. With a link to the repo as well, so curious folks can see how I managed to crash their browsers.

3

u/RandomGuy_A 5d ago

Impressive, you should take a look at libgdx and TeaVM , it compiles java to web assembly, has desktop and mobile builds too

2

u/According-Ad-7069 5d ago

Oh yes, they are awesome! TeaVM is what got me started on this journey, it's such an amazing tool! I've used LibGDX during my mobile dev days, it is also very underrated for what it's capable of.

3

u/Omenow 5d ago

Atleast on my 1440p fonts that are in canvas part are hard to read. So it's done with TeaVM? How drawing is done? I didn't done anything like that before.

3

u/According-Ad-7069 5d ago

Oh wow that's a huge resolution! It definitely won't work, sorry! I am going to redo the fonts, it's static bitmap fonts for now, but I'm busy working on that. It's just pixels, not via TeaVM, but I am going to open-source it so it's easier to explain.

3

u/wonderful_unikorn 4d ago

it's a good challenge to make games in Java

1

u/According-Ad-7069 4d ago

I find it's a good way to force me to revisit the basics and get back into the Java habit. I've been doing too much Python and Go!

2

u/International_Break2 5d ago

Unit movement could be more fluid if you are going for a more command and conquer aesthetic. Is this going to be open source at any point?

1

u/According-Ad-7069 5d ago

You know, unit movement is a bit blocky right now, I am trying to figure out how to use spatial grids better without lots of memory allocations. I am in two minds about open-sourcing. I did some of my previous games the hate I got because I wouldn't accept 9k line PR's got a bit much. I think I should blog about it, then release it in stages so someone can put it all together for themselves if they want, but I don't have to deal with the slop slingers.

3

u/International_Break2 5d ago

You can always be like sqlite and have the code public but never accept a pull request.

2

u/According-Ad-7069 5d ago

That's a good plan - just need to clean up some of my comments and code, it's not fit for public consumption...

1

u/According-Ad-7069 3d ago

u/International_Break2 it's up at https://github.com/ewaldhorn/wartech if you wanted to have a good laugh at some dodgy Java!

2

u/agentoutlier 5d ago

I can't believe how damn fast it loads. Like there are react apps that take longer. I'll try later today on an ancient macbook air 2011 as I'm curious.

This is TeaVM right?

4

u/According-Ad-7069 5d ago

I originally did it with TeaVM, but I wanted a faster build cycle, so I took an older project I had (Pascal compiler) that compiles directly to wasm and put a Java lexer on it. It's on https://wasmcoffee.com/ if you are interested. You can also run it offline (https://github.com/ewaldhorn/wasmcoffee_examples) which is how I mostly use it.

BIG DISCLAIMER: I built this for ME, so it makes some assumptions about how I work, the docs are a mess and generally, this isn't ready to rock and roll. As I build things with it, I discover so many little edge cases that I didn't think of.

Basically I just output really, really, really naive wasm32 opcodes, so it loads fast since it's a simple stream, like Pascal, but it does not have any of the JVM features one would expect, since it's not a JVM. It's Java syntax:

public void directCollectors(GameMap map, TopdownRtsGame game) {

for (int i = 0; i < game.unitCount; i++) {

var u = game.units[i];

if (u.isDestroyed() || u.faction != Faction.ENEMY || u.type != UnitType.COLLECTOR) continue;

if (u.crystalLoad >= Unit.MAX_LOAD) {

returnToRefinery(u, game);

} else if (!u.moving && !u.returningToRefinery) {

seekCrystals(u, map);

}

}

}

Just a different compiler.

3

u/agentoutlier 5d ago

Consider me impressed regardless of doc. You know there is an interesting thing about Pascal. There was this paper that considered how "green" a language is and I think they took compiling into account.

Pascal and Java were among the greenest languages (green being environment friendly). I will find the link later.

I have a feeling age wise we might be peers. Are you a Xennial?

Its a general vibe I get on reading your profile and comments.

2

u/According-Ad-7069 5d ago

Yes!! That's why I had such a blast building a Pascal interpreter and later a compiler. Old Wirth did an insanely good job of making the language simple and easy to parse, in one go. No tricky multi-step requirements.

When it came to supporting Java though, I quickly realised I need a few more steps, to get the lay of the land, so to speak. What I do with Java is I read the source files, figure out the order of the imports, then rewrite it as one super long memory file, so I can parse it top-down like I would with Pascal. It does mean that I am doing a lot of up-front work, but given that I'm doing it all in one thread, it was the simplest way for me to get to the point where I can just parse the code, without keeping a graph of dependencies which just breaks my old brain.

TIL about Xennial and that I am indeed on. Turbo Pascal was my first "proper" language, later Delphi, and boy, did I have fun with it!

2

u/robintegg 4d ago

Looks great. As someone who is just getting up to speed with the likes of teavm / wasm, I appreciate you sharing a project showing how high the bar can be for Java apps in a browser

2

u/According-Ad-7069 4d ago

Oh wow thank you, that's most kind of you. I'm working on cleaning up my incredibly messy code and build scripts. You know, it works on my machine, barely, kind of stuff. When that's done, I'll make the code available as well.

2

u/Scf37 4d ago

Java is truly awesome indeed. I have:
- image viewer, supporting 100+ formats and near instant startup
- several games, working both on desktop and in the browser
- command line tools for personal use

Nowadays, the only reason not to use Java is strict memory (~100 mb extra) or disk (~60 mb extra) usage constraints . Therefore, no reasons not to use Java for everything.

1

u/According-Ad-7069 4d ago

Oh that's neat!! Are you using TeaVM for the browser stuff? I have played with GraalVM for that as well, both are really fantastic!

2

u/Scf37 4d ago

TeaVM. as for compilation times, my engine is multiplatform, I do entire development on JVM, enjoying instant startup, debugging and testing features then deploy teavm compiled bundle.

GraalVM unfortunately is not an option right now because https://github.com/oracle/graal/issues/12219

1

u/According-Ad-7069 4d ago

Oh I see! I only target very limited wasm32 builds so that won't affect me at least. You do really impressive stuff it seems, nice!