Sign in to follow this  
Thatotherguy

Boss-based RTS games.

Recommended Posts

When I decided to start a new project for Carnegie Mellon University's Game Creation Society, I wanted to make a simple 2D RTS with traditional gameplay reminiscent of Total Annihilation, with networking and basic RTS unit types and resources. I put together a pretty robust engine, and brought it to the first meeting of the group. Most of the people there were nonplussed by my lack of imagination in design, so we got into a discussion about how to make something more interesting out of my engine. We eventually came around to the idea of having one team with all incredibly massive, powerful, expensive units, and another side with all tiny, cheap swarming units. We started talking about various interpretations of this theme until we stripped it down to the basics. "Think Godzilla versus the U.S. Army," someone said, and we all found that idea rather appealing. Once we realized that nobody knew how to do networking, we decided to make a single-player interpretation on the theme. Also not wanting to handle incredibly complex AI for the few weeks we had to do the project, we came up with an idea that was basically "Shadow of the Colossus meets Tower Defense meets Command and Conquer." We called it Project:Confidential. The idea behind Project: Confidential is that the player controls a traditional set of RTS units: tanks, artillery, infantry, etc. and must defend a few key structures (as in Tower Defense) from a giant, usually slow, monster. We went with the theme of 1950's B-movie monsters. We didn't want the gameplay to just be "rush the monster with tons of units until it dies," so we wanted to make each monster a puzzle; and each level would be designed in such a way as to make use of the monster's strengths and weaknesses. For example, we had plans of a floating brain monster that took over your units, and which had to be stopped by artillery; and a monster that sat in the sand with only its back exposed, but which utterly destroyed everything in front of it. Other ideas included monsters which had to be lured into key areas, like water, before they would take damage; or monsters which would teleport to new areas when they felt threatened. We quickly discovered that the reason bosses aren't included in most RTS games is because bosses traditionally are maintained in genres that require fine control by the player to defeat, and which have a recognizable pattern that the player must figure out and counter. RTS games don't generally offer fine levels of control, so any boss battle would usually reduce to "order these units to attack the boss until its dead". We tried to counter this tendency by giving the monsters "bodyguards" that would defeat player armies trying to swarm the monster, and by giving each monster a totally unique attack strategy. Most of these ideas never made it into the current build of the game, but we managed to nail down the basics. We'll be continuing the project further over the summer and next semester; so hopefully it will be more fleshed-out by then. You can try out the project here: RTSDemo.php.jnlp

Share this post


Link to post
Share on other sites
natives-linux.jar

That's probably already enough to figure out what's wrong, but just in case:

JNLPException[category: Security Error : Exception: null : LaunchDesc:
<jnlp spec="1.0+" codebase="http://www.kittsplace.com/klingenco/Confidential/" href="http://www.kittsplace.com/klingenco/Confidential/RTSDemo.jnlp">
<information>
<title>login</title>
<vendor>Thatotherguy</vendor>
<homepage href="http://slick.cokeandcode.com"/>
<description>RTS</description>
<description kind="short">RTS</description>
<icon href="http://www.kittsplace.com/klingenco/Confidential/shortcut.ico" height="16" width="16" kind="shortcut"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<update check="timeout" policy="always"/>
<resources>
<java max-heap-size="134217728" href="http://java.sun.com/products/autodl/j2se" version="1.5+"/>
<jar href="http://www.kittsplace.com/klingenco/Confidential/RTSDemo.jar" download="eager" main="false"/>
<jar href="http://www.kittsplace.com/klingenco/Confidential/thingle.jar" download="eager" main="false"/>
<jar href="http://www.kittsplace.com/klingenco/Confidential/xstream-1.3.1.jar" download="eager" main="false"/>
<jar href="http://www.kittsplace.com/klingenco/Confidential/res.jar" download="eager" main="false"/>
<extension href="http://slick.cokeandcode.com/demos/slick.jnlp" version="b237"/>
<java max-heap-size="134217728" href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
<nativelib href="http://www.kittsplace.com/klingenco/Confidential/natives-linux.jar" download="eager" main="false"/>
</resources>
<application-desc main-class="RTSDemo"/>
</jnlp> ]
at com.sun.javaws.LaunchDownload.checkSignedResourcesHelper(LaunchDownload.java:1321)
at com.sun.javaws.LaunchDownload.checkSignedResources(LaunchDownload.java:1162)
at com.sun.javaws.Launcher.prepareLaunchFile(Launcher.java:778)
at com.sun.javaws.Launcher.prepareToLaunch(Launcher.java:217)
at com.sun.javaws.Launcher.launch(Launcher.java:111)
at com.sun.javaws.Main.launchApp(Main.java:315)
at com.sun.javaws.Main.continueInSecureThread(Main.java:219)
at com.sun.javaws.Main$1.run(Main.java:107)
at java.lang.Thread.run(Thread.java:619)

Share this post


Link to post
Share on other sites
Gotcha. I need to sign the native libraries with my own keytool. They're signed by a third party right now. Thanks, I will fix that immediately.

Share this post


Link to post
Share on other sites
It's working now :)

Looks interesting.

It's a pain that you can't select multiple units. Can't really use GI's like that. It would also help if I knew what I was selecting without having to think about it by looking at the unit. In the same vein, I can't tell what's currently in the build queue, and canceling build does not refund any spent money.

With around 10 or 15 enemy units visible and attacking on screen, the framerate slows to 1 fps and the sound starts lagging. Usually it's around 20-30 fps, though.

Every time I lose the game, it goes into an infinite loop between showing the briefing screen and showing a new game (I saw a new barracks) whenever I click the mouse.

That giant crab can really one-shot all my big guns, tanks, and cleaners?

When running the game for the 2nd time without closing the browser, after it went into the loop, I once got this exception (but not always):

java.lang.NullPointerException
at sun.font.TrueTypeGlyphMapper.<init>(TrueTypeGlyphMapper.java:44)
at sun.font.TrueTypeFont.getMapper(TrueTypeFont.java:1161)
at sun.font.FileFontStrike.<init>(FileFontStrike.java:151)
at sun.font.FileFont.createStrike(FileFont.java:74)
at sun.font.Font2D.getStrike(Font2D.java:331)
at sun.font.Font2D.getStrike(Font2D.java:262)
at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
at sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:345)
at sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:336)
at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:284)
at sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:764)
at org.newdawn.slick.TrueTypeFont.getFontImage(TrueTypeFont.java:111)
at org.newdawn.slick.TrueTypeFont.createPlainSet(TrueTypeFont.java:157)
at org.newdawn.slick.TrueTypeFont.<init>(TrueTypeFont.java:90)
at org.newdawn.slick.thingle.internal.slick.SlickThinletFactory.<init>(SlickThinletFactory.java:36)
at StartScreen.init(StartScreen.java:37)
at Start.init(Start.java:55)
at org.newdawn.slick.state.StateBasedGame.init(StateBasedGame.java:155)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:357)
at RTSDemo.main(RTSDemo.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1171)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1117)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:966)
at com.sun.javaws.Launcher.run(Launcher.java:121)
at java.lang.Thread.run(Thread.java:619)



Share this post


Link to post
Share on other sites
You CAN select multiple units. Click and drag with the mouse from the top left to the bottom right. This is is box-select. You can also double-click on a unit to select all of that type of unit.


I'll see what I can do to reproduce your bug with the loading screen. Also, I have never seen that exception before.

The idea behind the crab's laser was that it was supposed to force you to micro-manage all of your units. It used to be that the laser did about half its current damage, and had no splash damage. When playtesting we discovered that the player could easily defeat the crab just by building a bunch of GIs or jeeps and throwing them at it.

I should probably have it give you the funds back when you cancel...

What specs are you running at? Turning off the frame manager, I can easily get 300+ FPS running on a Q6600 and high-end Nvidia card. Running on my laptop, which has a T9300 dual core, I get about 150 FPS. With the frame limiter I get 60FPS with little jumps every now and then. I haven't done much testing on other hardware.

Share this post


Link to post
Share on other sites
The performance goes down a bit as I keep playing the game (sort of "lags" a bit when I play the game for X amount of time).

Nice work so far though!

Quote:
Original post by Thatotherguy
We quickly discovered that the reason bosses aren't included in most RTS games is because bosses traditionally are maintained in genres that require fine control by the player to defeat, and which have a recognizable pattern that the player must figure out and counter. RTS games don't generally offer fine levels of control, so any boss battle would usually reduce to "order these units to attack the boss until its dead". We tried to counter this tendency by giving the monsters "bodyguards" that would defeat player armies trying to swarm the monster, and by giving each monster a totally unique attack strategy.

What if you have an RTS boss that consists of an enemy base with enemy units? Sure it would be just like what you have done before, but a bit bigger (larger territory, etc), with more sections (tactical areas you must capture, etc), and a lot tougher than the usual (more units, etc). That could be considered a form of Boss for the RTS genre.

[Edited by - Tangireon on May 5, 2009 9:26:44 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Thatotherguy
You CAN select multiple units. Click and drag with the mouse from the top left to the bottom right. This is is box-select. You can also double-click on a unit to select all of that type of unit.


Well, I've been trying that so far, but when I do box-select it doesn't select any unit at all. Maybe it's a Linux-specific input issue? Double clicking does work as you describe.

Edit: After experimenting some more with the box-select, I found that I can use it if I drag right-down from a top left corner, but not if I drag from any other corner.


Quote:
Original post by Thatotherguy
I'll see what I can do to reproduce your bug with the loading screen. Also, I have never seen that exception before.


I can't reliably reproduce that exception, but I can reliably reproduce the infinite loop when losing the game. Dunno what will happen if I win, I haven't managed to do that so far! :D


Quote:
Original post by Thatotherguy
The idea behind the crab's laser was that it was supposed to force you to micro-manage all of your units. It used to be that the laser did about half its current damage, and had no splash damage. When playtesting we discovered that the player could easily defeat the crab just by building a bunch of GIs or jeeps and throwing them at it.

I should probably have it give you the funds back when you cancel...

What specs are you running at? Turning off the frame manager, I can easily get 300+ FPS running on a Q6600 and high-end Nvidia card. Running on my laptop, which has a T9300 dual core, I get about 150 FPS. With the frame limiter I get 60FPS with little jumps every now and then. I haven't done much testing on other hardware.


My specs are: Pentium 4 at 3.0 Ghz, 3 GB ram, geforce 8600 GT with 1 GB ram, running Ubuntu 8.10. and sun-java-6u10 (1.6.0_10-b33). LWJGL programs usually run just fine though.

I've also dropped the frame-rate to 1 fps by spamming GI's. Even though it says 1, nothing is actually moving anymore, so it's more like zero ^_^;;; At the very start of the game, I get about 50-65 fps. After doing nothing except producing 30 GIs, fps drops to single digits. At 40 GIs it's already unplayable.

Another thing I noticed, there are black horizontal lines appearing when I zoom in or out. Maybe due to vsync.

[Edited by - lightbringer on May 5, 2009 10:01:23 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by MortusMaximus
For some reason, it keeps telling me the download stalled.


The server is slow. It will stall for a few minutes and then continue.

Share this post


Link to post
Share on other sites
Here's some output of the built-in profiling, doing nothing but building 40 GI's and then leaving it for a couple of minutes. I'm not an expert at this but it looks like the collision detection could be bogging down the game. Most of the time is spent on StrictMath.atan2() and Shape.intersects()


Flat profile of 398.43 secs (25962 total ticks): Thread-21

Thread-local ticks:
100.0% 25962 Blocked (of total)


Flat profile of 404.71 secs (26443 total ticks): Thread-20

Thread-local ticks:
100.0% 26443 Blocked (of total)


Flat profile of 412.87 secs (26562 total ticks): Thread-18

Thread-local ticks:
100.0% 26562 Blocked (of total)


Flat profile of 414.22 secs (26659 total ticks): javawsApplicationMain

Interpreted + native Method
0.6% 167 + 0 java.util.ArrayList.size
0.3% 74 + 0 java.util.LinkedList.size
0.1% 26 + 1 sun.misc.Unsafe.defineClass
0.1% 0 + 24 org.lwjgl.opengl.LinuxContextImplementation.nSwapBuffers
0.1% 0 + 23 org.lwjgl.openal.ALC10.nalcCloseDevice
0.1% 0 + 19 java.lang.Class.getDeclaredConstructors0
0.0% 10 + 1 java.lang.ClassLoader.defineClass1
0.0% 0 + 10 sun.font.FileFont.getGlyphImage
0.0% 10 + 0 java.nio.HeapByteBuffer.<init>
0.0% 10 + 0 com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.<init>
0.0% 0 + 9 org.lwjgl.opengl.GL11.nglPopAttrib
0.0% 0 + 9 java.util.zip.Inflater.inflateBytes
0.0% 0 + 9 org.lwjgl.opengl.LinuxMouse.nGetWindowHeight
0.0% 0 + 9 org.lwjgl.opengl.GL11.nglTexImage2D
0.0% 9 + 0 com.sun.org.apache.xerces.internal.parsers.XML11Configuration.<init>
0.0% 0 + 8 java.lang.SecurityManager.getClassContext
0.0% 0 + 8 org.lwjgl.opengl.LinuxDisplay.nCreateBlankCursor
0.0% 8 + 0 sun.reflect.MethodAccessorGenerator.emitInvoke
0.0% 0 + 7 java.util.zip.Inflater.init
0.0% 0 + 7 org.lwjgl.opengl.LinuxKeyboard.openIM
0.0% 2 + 5 java.io.UnixFileSystem.getLastModifiedTime
0.0% 0 + 7 org.lwjgl.opengl.GL11.nglPushAttrib
0.0% 7 + 0 com.sun.org.apache.xerces.internal.dom.ParentNode.ownerDocument
0.0% 7 + 0 com.thoughtworks.xstream.io.path.PathTracker.<init>
0.0% 0 + 6 org.lwjgl.opengl.GL11.nglClear
3.3% 575 + 294 Total interpreted (including elided)

Compiled + native Method
23.8% 6221 + 0 org.newdawn.slick.geom.Shape.intersects
9.7% 2480 + 48 org.newdawn.slick.geom.Line.<init>
2.6% 686 + 0 org.newdawn.slick.geom.Shape.checkPoints
2.5% 658 + 1 org.newdawn.slick.particles.ParticleSystem.update
2.3% 496 + 92 AI.avoidotherUnits
1.5% 390 + 0 RTSMap.blocked
1.2% 320 + 0 java.util.LinkedList.entry
1.2% 298 + 3 org.newdawn.slick.geom.Ellipse.createPoints
1.0% 270 + 1 AStar$PriorityList.add
0.7% 186 + 0 java.lang.String.indexOf
0.7% 184 + 1 Game.update
0.5% 138 + 0 AStar.findPath
0.5% 120 + 0 java.util.ArrayList.get
0.4% 110 + 5 org.newdawn.slick.geom.Shape.findCenter
0.4% 112 + 0 org.newdawn.slick.geom.NeatTriangulator.snip
0.4% 110 + 0 org.newdawn.slick.geom.Shape.calculateRadius
0.4% 93 + 7 Movable.move
0.4% 94 + 0 org.newdawn.slick.geom.NeatTriangulator.findEdge
0.3% 76 + 0 java.util.LinkedList.indexOf
0.3% 71 + 0 AI.targetEnemies
0.3% 66 + 0 org.newdawn.slick.particles.ConfigurableEmitter.updateParticle
0.2% 65 + 0 java.util.AbstractList$Itr.next
0.2% 58 + 3 Ent.act
0.2% 58 + 0 AStar.isValidLocation
0.2% 56 + 0 java.lang.String.indexOf
55.8% 14333 + 227 Total compiled (including elided)

Stub + native Method
31.8% 0 + 8294 java.lang.StrictMath.atan2
1.5% 0 + 384 org.lwjgl.opengl.GL11.nglVertex3f
1.4% 0 + 365 org.lwjgl.opengl.GL11.nglTexCoord2f
1.0% 0 + 253 org.lwjgl.opengl.GL11.nglColor4f
0.8% 0 + 221 org.lwjgl.opengl.GL11.nglDisable
0.4% 0 + 111 java.util.zip.Inflater.inflateBytes
0.3% 0 + 87 java.lang.Class.isPrimitive
0.3% 0 + 80 org.lwjgl.opengl.GL11.nglBegin
0.3% 0 + 74 org.lwjgl.opengl.GL11.nglEnd
0.3% 23 + 48 java.security.AccessController.doPrivileged
0.3% 0 + 67 java.security.AccessController.getStackAccessControlContext
0.3% 0 + 67 java.lang.Class.getSuperclass
0.2% 0 + 58 org.lwjgl.opengl.GL11.nglVertex2f
0.2% 0 + 57 java.nio.Bits.copyFromByteArray
0.2% 0 + 56 java.lang.String.intern
0.2% 0 + 54 java.util.zip.ZipFile.getEntry
0.1% 0 + 34 java.lang.System.arraycopy
0.1% 0 + 30 org.lwjgl.opengl.GL11.nglTranslatef
0.1% 0 + 28 sun.reflect.Reflection.getCallerClass
0.1% 0 + 26 java.lang.Object.clone
0.1% 0 + 22 java.lang.Class.getClassLoader0
0.1% 0 + 22 java.lang.ClassLoader.findLoadedClass0
0.1% 0 + 17 java.lang.Object.hashCode
0.1% 0 + 17 java.lang.Throwable.fillInStackTrace
0.1% 0 + 15 org.lwjgl.opengl.GL11.nglCallList
40.8% 34 + 10619 Total stub (including elided)

Thread-local ticks:
2.2% 574 Blocked (of total)
0.0% 3 Class loader


Flat profile of 418.74 secs (27045 total ticks): TimerQueue

Thread-local ticks:
100.0% 27045 Blocked (of total)


Flat profile of 418.84 secs (27053 total ticks): CacheCleanUpThread

Thread-local ticks:
100.0% 27053 Blocked (of total)


Flat profile of 418.85 secs (27053 total ticks): CacheMemoryCleanUpThread

Compiled + native Method
50.0% 0 + 1 java.lang.ref.ReferenceQueue.remove
50.0% 0 + 1 Total compiled

Stub + native Method
50.0% 0 + 1 java.lang.Object.hashCode
50.0% 0 + 1 Total stub

Thread-local ticks:
100.0% 27051 Blocked (of total)


Flat profile of 418.86 secs (27053 total ticks): ConsoleWriterThread

Interpreted + native Method
100.0% 1 + 0 java.awt.EventQueue.postEventPrivate
100.0% 1 + 0 Total interpreted

Thread-local ticks:
100.0% 27052 Blocked (of total)


Flat profile of 418.87 secs (27054 total ticks): AWT-EventQueue-1

Interpreted + native Method
31.8% 0 + 88 com.sun.java.swing.plaf.gtk.GTKNativeEngine.nativeFinishPainting
19.5% 0 + 54 sun.java2d.loops.DrawGlyphListAA.DrawGlyphListAA
10.8% 2 + 28 sun.java2d.loops.MaskBlit.MaskBlit
7.2% 0 + 20 sun.java2d.loops.Blit.Blit
6.1% 0 + 17 sun.awt.X11.XInputMethod.openXIMNative
4.0% 0 + 11 sun.misc.Unsafe.unpark
3.6% 0 + 10 com.sun.java.swing.plaf.gtk.GTKNativeEngine.native_paint_box
1.1% 0 + 3 java.lang.System.identityHashCode
1.1% 0 + 3 sun.java2d.x11.X11CachingSurfaceManager.updateBitmask
0.7% 0 + 2 sun.misc.Unsafe.allocateMemory
0.7% 0 + 2 com.sun.java.swing.plaf.gtk.GTKNativeEngine.nativeStartPainting
0.7% 2 + 0 sun.font.GlyphList.getInstance
0.7% 2 + 0 com.sun.java.swing.plaf.gtk.GTKNativeEngine.finishPainting
0.7% 2 + 0 javax.swing.plaf.synth.SynthGraphicsUtils.paintText
0.4% 0 + 1 java.security.AccessController.doPrivileged
0.4% 0 + 1 sun.font.FontManager.getFont2D
0.4% 0 + 1 sun.awt.X11.XlibWrapper.XFlush
0.4% 0 + 1 sun.font.FileFont.getGlyphImage
0.4% 1 + 0 javax.swing.text.SegmentCache.getSharedInstance
0.4% 0 + 1 sun.awt.image.BufImgSurfaceData.initRaster
0.4% 1 + 0 sun.java2d.SunGraphics2D.clipRect
0.4% 1 + 0 java.util.IdentityHashMap.clear
0.4% 1 + 0 java.awt.Window.postWindowEvent
0.4% 1 + 0 java.util.concurrent.locks.AbstractQueuedSynchronizer.addWaiter
0.4% 1 + 0 java.util.concurrent.locks.AbstractQueuedSynchronizer.unparkSuccessor
94.6% 19 + 243 Total interpreted (including elided)

Compiled + native Method
0.4% 0 + 1 sun.swing.ImageCache.getEntry
0.4% 0 + 1 java.awt.Container.findComponentAtImpl
0.7% 0 + 2 Total compiled

Stub + native Method
1.4% 0 + 4 java.lang.Object.getClass
0.7% 0 + 2 java.lang.Object.hashCode
0.7% 0 + 2 java.lang.System.identityHashCode
0.7% 0 + 2 java.lang.Object.clone
0.4% 0 + 1 java.lang.Thread.currentThread
0.4% 0 + 1 java.security.AccessController.getStackAccessControlContext
4.3% 0 + 12 Total stub

Thread-local ticks:
99.0% 26777 Blocked (of total)
0.4% 1 Interpreter


Flat profile of 419.08 secs (27074 total ticks): AWT-EventQueue-0

Thread-local ticks:
100.0% 27074 Blocked (of total)


Flat profile of 419.08 secs (27074 total ticks): AWT-Shutdown

Interpreted + native Method
100.0% 0 + 1 java.lang.Object.wait
100.0% 0 + 1 Total interpreted

Thread-local ticks:
100.0% 27073 Blocked (of total)


Flat profile of 419.14 secs (27079 total ticks): traceMsgQueueThread

Interpreted + native Method
50.0% 1 + 0 java.lang.StringBuffer.length
50.0% 1 + 0 com.sun.deploy.util.ConsoleTraceListener.print
100.0% 2 + 0 Total interpreted

Thread-local ticks:
100.0% 27077 Blocked (of total)


Flat profile of 419.15 secs (27079 total ticks): DestroyJavaVM

Thread-local ticks:
100.0% 27079 Blocked (of total)


Flat profile of 419.16 secs (27080 total ticks): Javaws Secure Thread

Thread-local ticks:
100.0% 27080 Blocked (of total)


Flat profile of 419.16 secs (27080 total ticks): AWT-XAWT

Interpreted + native Method
99.7% 1 + 26863 sun.awt.X11.XToolkit.waitForEvents
0.1% 0 + 20 sun.awt.X11.XlibWrapper.XQueryTree
0.0% 0 + 11 sun.awt.X11.XlibWrapper.XFilterEvent
0.0% 0 + 7 java.lang.Thread.yield
0.0% 0 + 7 sun.awt.X11.XlibWrapper.XSync
0.0% 5 + 0 java.awt.EventQueue.wakeup
0.0% 0 + 4 sun.awt.X11.XlibWrapper.XTranslateCoordinates
0.0% 0 + 2 sun.misc.Unsafe.unpark
0.0% 0 + 2 sun.awt.X11.XlibWrapper.XGetWindowProperty
0.0% 2 + 0 java.util.concurrent.locks.AbstractQueuedSynchronizer.addWaiter
0.0% 0 + 1 sun.awt.X11.XlibWrapper.XEventsQueued
0.0% 0 + 1 sun.awt.X11.XlibWrapper.InternAtom
0.0% 0 + 1 sun.misc.Unsafe.compareAndSwapObject
0.0% 1 + 0 sun.awt.X11.XWindowPeer.handlePropertyNotify
100.0% 9 + 26919 Total interpreted

Stub + native Method
0.0% 0 + 3 java.lang.Object.getClass
0.0% 0 + 2 sun.awt.X11.XlibWrapper.XEventsQueued
0.0% 0 + 1 java.lang.Object.clone
0.0% 0 + 6 Total stub

Thread-local ticks:
0.5% 146 Blocked (of total)


Flat profile of 419.35 secs (27093 total ticks): Java2D Disposer

Thread-local ticks:
100.0% 27093 Blocked (of total)


Global summary of 419.48 seconds:
100.0% 28462 Received ticks
4.3% 1234 Received GC ticks
0.5% 129 Compilation
0.4% 111 Other VM operations
0.0% 6 Class loader
0.0% 1 Interpreter
0.0% 3 Unknown code



Share this post


Link to post
Share on other sites
Quote:
Original post by lightbringer


Edit: After experimenting some more with the box-select, I found that I can use it if I drag right-down from a top left corner, but not if I drag from any other corner.


That's correct. I guess I just never tested selecting from other corners. I think I may be mis-representing the box (ie, it has a negative width).


Quote:
Original post by lightbringer
I can't reliably reproduce that exception, but I can reliably reproduce the infinite loop when losing the game. Dunno what will happen if I win, I haven't managed to do that so far! :D


I cannot reproduce this. I will try again.


Quote:
Original post by lightbringer
My specs are: Pentium 4 at 3.0 Ghz, 3 GB ram, geforce 8600 GT with 1 GB ram, running Ubuntu 8.10. and sun-java-6u10 (1.6.0_10-b33). LWJGL programs usually run just fine though.

I've also dropped the frame-rate to 1 fps by spamming GI's. Even though it says 1, nothing is actually moving anymore, so it's more like zero ^_^;;; At the very start of the game, I get about 50-65 fps. After doing nothing except producing 30 GIs, fps drops to single digits. At 40 GIs it's already unplayable.

Another thing I noticed, there are black horizontal lines appearing when I zoom in or out. Maybe due to vsync.


Okay,sounds like CPU, probably related to pathfinding. GIs tend to rape the framerate because you can build so many of them and they collide often.

I can reproduce this too on my machine. Buildling too many GIs will almost certainly cause the frame rate to die. I'm not exactly sure what to do to make this better. It would probably require serious changes to my engine.

Black lines occur on all Nvidia cards. This is an issue with the tile map format I am using, and I'm not sure how to fix it. It is probably related to scaling of images messing up the tiling on the background.

Share this post


Link to post
Share on other sites
What you can do, if you aren't doing it already, is reduce the number of collision tests by only testing for nearby collision targets (you can split them up using any scheme that makes sense, whether it's a regular grid or quadtrees. I would also investigate the viability of alternatives to StrictMath if I were you.

Pathfinding in general could be smoother - I often see things such as a tank stuck oscillating when trying to pass in a narrow space, such as between a house and a nearby turret.

I also noticed that the uranium bar at the top keeps changing shape when it's depleting (horizontally expanding/contracting or jumping up and down). This only seems to happen when zoomed in all the way, or when many units are produced (or maybe both, I'm not certain about it).

About the loop after endgame, here's what happens:

Tue May 05 18:39:57 CEST 2009 ERROR:Resource not found: /res/tiletemplate.png
java.lang.RuntimeException: Resource not found: /res/tiletemplate.png
at org.newdawn.slick.util.ResourceLoader.getResourceAsStream(ResourceLoader.java:69)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:159)
at org.newdawn.slick.Image.<init>(Image.java:152)
at org.newdawn.slick.tiled.TiledMap$TileSet.<init>(TiledMap.java:540)
at org.newdawn.slick.tiled.TiledMap.load(TiledMap.java:419)
at org.newdawn.slick.tiled.TiledMap.<init>(TiledMap.java:94)
at Game.checkGameStatus(Game.java:1302)
at Game.update(Game.java:424)
at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:252)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:541)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:371)
at RTSDemo.main(RTSDemo.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1171)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1117)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:966)
at com.sun.javaws.Launcher.run(Launcher.java:121)
at java.lang.Thread.run(Thread.java:619)
org.newdawn.slick.SlickException: Failed to parse tilemap
at org.newdawn.slick.tiled.TiledMap.load(TiledMap.java:440)
at org.newdawn.slick.tiled.TiledMap.<init>(TiledMap.java:94)
at Game.checkGameStatus(Game.java:1302)
at Game.update(Game.java:424)
at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:252)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:541)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:371)
at RTSDemo.main(RTSDemo.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1171)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1117)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:966)
at com.sun.javaws.Launcher.run(Launcher.java:121)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.RuntimeException: Resource not found: /res/tiletemplate.png
at org.newdawn.slick.util.ResourceLoader.getResourceAsStream(ResourceLoader.java:69)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:159)
at org.newdawn.slick.Image.<init>(Image.java:152)
at org.newdawn.slick.tiled.TiledMap$TileSet.<init>(TiledMap.java:540)
at org.newdawn.slick.tiled.TiledMap.load(TiledMap.java:419)
... 16 more



Share this post


Link to post
Share on other sites
Yep, collisions look like the big bottleneck.

Currently I am using the "stupid method" for collisions (ie, I use an n^2 loop to check and see if GI i intersects GI j, and then apply a force)

A quad tree would probably be a better idea. I just never learned how to do quad tree collision detection. I should probably read up on this now.

EDIT: To make a quad tree, I'd have to come up with some kind of hashed data structure and then remove and add units constantly as their positions change. Is this really efficient?

As for the exception; it really doesn't make much sense. I call the exact line it is complaining about when you start the game, and it didn't crash for you then, did it?

Also, I updated the game to fix the selection rectangle bug.

Thanks for testing, guys.

[Edited by - Thatotherguy on May 5, 2009 12:05:54 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Thatotherguy
EDIT: To make a quad tree, I'd have to come up with some kind of hashed data structure and then remove and add units constantly as their positions change. Is this really efficient?

Collision testing against every object in the scene obviously doesn't scale - many games use at least spatial partitioning to get around this. You can also eliminate double tests by remembering which pairs were already tested. You don't have to update the partitions every frame, either.

Quote:
Original post by Thatotherguy
As for the exception; it really doesn't make much sense. I call the exact line it is complaining about when you start the game, and it didn't crash for you then, did it?

Nope, only when it goes into this loop after losing. The exception keeps looping, too.

Share this post


Link to post
Share on other sites
I partitioned the space into a giant hash map that uses seperate chaining, considering each tile on the map to be a bucket in which things can collide. If a unit intersects multiple tile maps, they get mapped to several buckets in the collision map. Then, when they want to see what they're colliding with, they poll the collision map and it returns a list of entities in the same grid square as they are.

I also removed the frame limiter.

I'm not sure if this is any faster, but I was able to spam about 20 more GIs than usual. The crux is, GIs are so small that maybe 10-20 of them can fit on a square. So, I'll have to further divide the space and do a real quad tree implementation to see real performance increases.

Share this post


Link to post
Share on other sites
Quote:
Original post by Thatotherguy
I partitioned the space into a giant hash map that uses seperate chaining, [...] in the same grid square as they are


Why not just use an array of some kind? What extra benefit does the hash map get you?
Then, when you encounter a "bucket" with entities, instead of testing 3 entities like this:
a -> b
a -> c
b -> a
b -> c
c -> a
c -> b
Test them like this:
a -> b
a -> c
b -> c
And mark the "bucket" as processed so (if you're iterating entities) you don't go and test them again. Just don't forget to reset the buckets to unprocessed at the end of the frame.

Share this post


Link to post
Share on other sites

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