Jump to content

Ykkrosh

WFG Retired
  • Posts

    4.928
  • Joined

  • Last visited

  • Days Won

    6

Everything posted by Ykkrosh

  1. Yeah, I think it's important to consider the problems and limitations with the current approach before jumping into a new one. Some random thoughts on the current state of things and how I imagine it could be improved: Currently music is handled via hacky GUI JS code, which is the wrong place for it - music needs to persist (and smoothly crossfade etc) across multiple GUI pages, so it shouldn't be controlled by code that's inside a GUI page. It doesn't need to do anything very fancy - play menu music, or victory/defeat music, or civ-dependent session music, and switch the session music to combat/peace as appropriate, and that's probably about all. Ideally it would smoothly crossfade even if the game's main thread is stalled (e.g. while loading a map). Currently ambient sound (birdsong etc) is handled the same way as music (i.e. badly). It might make sense to continue doing that, with a sensibly-designed music+ambience manager. (Music and ambient sounds are both long and ought to be streamed from the in-memory Vorbis content, whereas standard sound effects can be fully decompressed in advance.) Currently we map the 3D world-space positions of the camera and units directly into OpenAL's 3D positional audio. That's not appropriate for an RTS-style camera - I believe (though not based on any evidence or testing) players expect to hear what's visible on the screen, rather than expecting to hear what would be physically realistic if they were floating in a hot air balloon above the battlefield. A unit in the middle of the screen (nearest the camera) is no more visible to the player than a unit that's near the edge of the screen (further from the camera in 3D), but those are far more visible than a unit that's just past the edge of the screen (only a little further from the camera), so a sound's volume should intuitively depend on 2D distance from screen edges rather than on 3D distance from camera. It's still useful to hear some sounds that are outside the screen, e.g. combat sounds (telling the player that they should pan in that direction because there's a battle going on that they might have missed), while others are unwanted distractions, e.g. cows mooing (a nice ambient effect but pointless if you can't actually see the cow); so different sounds should have different falloff behaviour. When zooming out, it'd probably make sense to make all the units somewhat quieter (to compensate for there being more visible at once and for them looking smaller) and maybe increase the volume of ambient wind etc. The precise details likely need endless tweaking, but I think the important basic principle is that the sound designers select screen-based volume falloff (not 3D distance-based falloff), and that the engine applies some arbitrary transformation from the original 3D positions and camera and zoom and screen size etc to produce the final 3D positions that are passed to OpenAL. Currently the engine can only trigger a sound to play immediately and independently. That makes the intensity concept infeasible to implement well - we can't detect there's a lot of combat sounds and replace some of them with a single high-intensity battle sample, because the sound system will have already started playing all the individual combat sounds, and because the sound system isn't made aware of gameplay concepts like "combat" (all it knows about is the individual sound groups). (I think the intensity concept is valuable since it lets the sound designers make large battles sound good, and would also help when formations of units are given commands (you can't just repeat one "yes sir" speech sample for every unit because you get nasty phasing effects, it'd be better to have a pre-mixed large-number-of-people-saying-the-same-thing sample), so it should be worth supporting it properly). It's often feasible for the engine (and/or gameplay scripts) to tell the sound system that an effect should be played, some hundreds of milliseconds before it's needed. (E.g. it knows a unit is in the 'attack' state so it can calculate when the animation will reach the point that triggers the sound, assuming nothing unexpected (e.g. death) occurs in the meantime)). Also it could pass extra data to the sound system, e.g. adding a "combat" tag to the sound. Hopefully that would be enough for the sound system to build up a global picture of everything that's playing now or that will start soon, and if the total combat sounds exceed some intensity threshold then it can disable some of the not-yet-played ones and fade in the high-intensity battle sample, or something like that. Again I haven't thought through the precise details, so this could be totally wrong or overcomplicated, but I think the important general idea is to have a sound manager that isn't entirely short-sighted like the current implementation and that can analyse the whole soundscape. Currently I don't think there's a distinction between music, ambience, effects, etc. All sounds should be classified into a small number of groups so players can adjust the volume of each group individually (e.g. if they hate our music, or if the ambience distracts from the important gameplay effects). Currently the behaviour of sounds is defined in sound group XML files. Those files are pretty verbose and ugly and low-level - I think the general principle (of a sound group defining all the playback parameters and listing the individual .ogg files to randomly pick from) is probably fine, but the format should be cleaned up (and probably use some kind of inheritance system (as with entities and textures etc) so you don't have to repeat common parameters).
  2. The current game design is meant to be focused on the period from 500 BC to 1 BC, so Jesus just misses out . (Also it's meant to be based on real history, not on largely fictional representations of people, so mystical healing powers would probably be inappropriate )
  3. SDL isn't relevant (we don't use it for anything except setting up the initial window and handling input) - I think we'd primarily just need a way to render a paragraph into a bitmap at runtime, which should be fairly easy with Pango + Cairo, then we can convert it to an OpenGL texture and render it. (Plus some caching to maintain decent performance, and some extra integration with the GUI layout code, etc.)
  4. Arabic and Hebrew can't work properly since our GUI engine doesn't support RTL/bidi text (and support would probably be quite hard to add; I expect we'd have to redesign and rewrite all the GUI text layout code, probably using something like Pango), and also I believe Arabic needs complex font shaping support (our text renderer assumes each Unicode codepoint corresponds to a single independent glyph bitmap; I expect we'd have to change to using Pango/HarfBuzz to render runs of text at run-time to handle that properly, which should be less hard than bidi but still quite hard). Georgian (at least modern Mkhedruli, apparently) looks like it has neither of those problems, so it ought to mostly work fine if it's added to the bitmap fonts (need to add to the character list and rerun the fontbuilder script; but the current serif font (TeX Gyre Pagella) doesn't include those glyphs, so we'd need to find a decent free font and update the script to use that for the relevant Unicode blocks).
  5. The game should build fine with 1.2 or recent 1.3/2.0 (we use 1.2 on standard desktop Linux). We run with OpenAL-Soft on Windows, so it does support what we need, but I don't think anyone has seriously examined audio support for Android yet, so I don't know if that'd be a good solution or not. Probably worth looking into.
  6. There are no branches, so you should use the latest SVN trunk code. SDL 1.3 got renamed to 2.0, and 1.2 doesn't support touchscreens, so you should use 2.0. For data, you should do the archivebuild thing from #155. This whole Android support is pretty rough so it probably won't work trivially, but hopefully it'll be possible to get something running
  7. Hmm, I think this is an unexpected consequence of Atlas saving things into bogus locations, combined with the uninstaller assuming the cache directory can be safely deleted. (The uninstaller is doing what it should, but we should have a proper location for storing user-created content.)
  8. They're form feed characters (intended mainly to help people who are printing the text file on a printer from last century) and are in the original license text, so it's not a bug.
  9. Ah, indeed - it seems Windows doesn't like alpha-blended cursors except on 32-bit displays. (I tested with recent NVIDIA drivers on Win7). A few other people have reported the same problem before, but we never knew what caused it, so thanks for experimenting! I've got a fix so that the game falls back to OpenGL-rendered cursors in that case - I'll probably commit that after the next alpha release (don't want to introduce any unexpected side-effects before then).
  10. I read the first book then saw the TV series then read the next three* books afterwards, and I don't think that seeing the TV series detracted from the later books for me - it's very close to the book in terms of plot so it doesn't lead to confusion over inconsistencies, and the characters are mostly the same (though with a few small changes that made me evaluate the book characters slightly differently, which was probably an improvement), and I didn't mind the characters being given faces and voices (I suppose I'm generally not a very visual reader so I didn't have problems with the TV series differing from strong images in my imagination). (* counting the split-volume book 3 as one; I haven't got to the recently-released one yet, but it looks like it's out in paperback later this week, so I guess I might as well start that soon.) Where 4 = A Feast for Crows? I think I found it quite comparable to the earlier books, so if you find them adequately enjoyable then there's no reason not to read the later ones (On a similar vein, I've recently read some stuff by Joe Abercrombie, who seems to be frequently compared to GRRM, so that might be a good place to look for anyone wanting more generally-not-very-magical fantasy with generally-a-bit-nasty characters but with more humour and less amateurish book covers (at least in the UK editions).)
  11. Ykkrosh

    New Error!

    I forget which number we're on - I just mean whichever is the first version we haven't released yet I think hiding it from the list entirely would potentially confuse players, and they'd worry that upgrading the game had deleted all their old saves. Also it would prevent them from choosing to delete the old saves (assuming the game had some UI to delete saves, which it doesn't yet). But adding some marker to indicate old saves in the list would be fine.
  12. No - every player runs the script independently. (The generated map data can be quite large, so it would be slow to upload it to every player.) That's potentially problematic. There's some examples here of where functions return different results; presumably the values often get rounded to integer tiles, but in some cases the difference will cause the value to cross the rounding boundary and cause OOS. (The OOS check doesn't verify the terrain data directly, so you'll only notice when the difference influences the behaviour of an entity.)
  13. Depends what you mean by "should" . I think the language rule is basically that you can always replace a semicolon by a newline, but our (rather incomplete) coding conventions are that you should always include an explicit semicolon.
  14. Be careful that trigonometric functions in JS don't return precisely identical results on different platforms (Windows vs Linux etc), so they'll probably cause out-of-sync errors in multiplayer. It's best to avoid them entirely if at all possible (and prefer using vectors maths rather than trigonometry); otherwise we'll probably have to replace the standard versions of the functions with 'safe' (but likely slow and imprecise) versions.
  15. Ykkrosh

    New Error!

    Yeah, that will cause a wide variety of random errors depending on how it misinterprets the binary stream. (We should update the version numbers in source/ps/SavedGame.cpp when changing components incompatibly (or at least increment it for each official release), though first we should make the GUI file-loading code detect old versions and complain instead of blindly attempting to load them. I suppose that would be valuable for the next alpha release, since it's the first release where normal players are likely to have incompatible saves.)
  16. It might be useful to know the lines logged by the engine before it crashes - it's possible that it's reporting an error and then abort()ing. Otherwise, addr2line might help - give it libpyrogenesis_dbg.so and address "00a6cdc4" (from the stack), and also get a copy of your /system/lib/libc.so (I think "adb pull" should be able to do that) and run addr2line with libc.so and maybe addresses "000161e0" and "00019711" and "00018a33" and "00018825" and "0001cd37".
  17. That says: I/DEBUG (21117): Build fingerprint: 'samsung/GT-I9103/GT-I9103:2.3.5/GINGERBREAD/XWKI5:user/release-keys' I/DEBUG (21117): pid: 22328, tid: 22337 >>> org.libsdl.app <<< I/DEBUG (21117): signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 823ed560 I/DEBUG (21117): r0 00082c20 r1 00000000 r2 00000001 r3 82c20e28 I/DEBUG (21117): r4 82c002ac r5 0000010f r6 00000004 r7 480e89c8 I/DEBUG (21117): r8 480e8b40 r9 40086fb8 10 40086fa4 fp 802a5374 I/DEBUG (21117): ip 82c00390 sp 480e89c8 lr 823ed4e7 pc 823ed560 cpsr 20000030 [...] I/DEBUG (21117): #00 pc 003ed560 /data/local/libpyrogenesis_dbg.so I/DEBUG (21117): #01 lr 823ed4e7 /data/local/libpyrogenesis_dbg.so I/DEBUG (21117): I/DEBUG (21117): code around pc: I/DEBUG (21117): 823ed540 00001608 b085b590 4c2aaf00 6078447c I/DEBUG (21117): 823ed550 58e34b29 60fb681b eeff687b edc30b00 I/DEBUG (21117): 823ed560 687b0b10 0200f04f 687b60da 0200f04f I/DEBUG (21117): 823ed570 687b611a 0200f04f 687b615a 4b1f681a I/DEBUG (21117): 823ed580 681b447b 46194610 e18ef20d 46184603 [...] I/DEBUG (21117): stack: [...] I/DEBUG (21117): #00 480e89c8 00000004 [...] I/DEBUG (21117): 480e89e4 823ed4e7 /data/local/libpyrogenesis_dbg.so [...] I/DEBUG (21117): 480e8a0c 823ef25f /data/local/libpyrogenesis_dbg.so so to (hopefully) see where it's failing, run ~/android/toolchain-0ad/bin/arm-linux-androideabi-addr2line -e binaries/system/libpyrogenesis_dbg.so 003ed560 ~/android/toolchain-0ad/bin/arm-linux-androideabi-addr2line -e binaries/system/libpyrogenesis_dbg.so 003ed4e7 ~/android/toolchain-0ad/bin/arm-linux-androideabi-addr2line -e binaries/system/libpyrogenesis_dbg.so 003ef25f (pc is current function, lr is caller, and any line after #00 in the stack that's labelled with the .so name is probably part of the call stack. You need to mask off the leading "82" in the addresses because the code was relocated at runtime, I think.) Since this is an ILL_ILLOPC (illegal opcode), I think it's most likely due to differences in CPU. Galaxy R apparently uses Tegra 2, which is Cortex-A9 (like Galaxy S2) but without NEON (unlike Galaxy S2), and the game is compiled to assume NEON support. Try editing build/premake/premake4.lua and remove the "-mfpu=neon", and also edit build/android/setup-libs.sh to remove the "-mfpu=neon", then clean and rebuild everything, and it might be happier. (In particular, the instruction just before the pc (i.e. the one whose execution triggered the exception, if I understand this correctly) is "edc30b00", which is "vstr d16, [r3, #64]" and therefore requires NEON support, so that seems a plausible explanation. Edit: Oops, I keep getting confused by endianness. The vstr is actually "edc3 0b10", and the problem is more likely the earlier "eeff 0b00 fconstd d16, #240" starting at 823ed55a, though I don't understand quite how the reported pc value (6 bytes later) relates to that.)
  18. Oh, forgot to mention that I also changed the script to use r7-crystax-5.beta2, which fixes the HTTP-based profiler (r7-crystax-4 overrides the standard socket functions and then doesn't actually implement select() so everything breaks confusingly). If you don't care about the profiler then changing it back to the earlier NDK version should work.
  19. As far as I'm aware, /sdcard is not an SD card - it's just a partition of the standard built-in Flash storage. (The SGS2 apparently has 16GB of storage, split into ~2GiB of "device memory" for applications, 11.5GiB of "USB storage" for data or large applications, and presumably ~2GiB for system stuff). (The optional external SD card gets mounted into /sdcard/external_sd instead). So I think in theory it shouldn't make a difference on this device, though I've never tested it. Since loading performance isn't too bad anyway (and I'd suspect it's mostly CPU-bound), and the "device memory" is pretty small, and it's hard to upload/download files to device memory (I think the only way is 'adb push' to /data/data/local/, and the USB connection is much slower than copying with SFTP over wifi), it doesn't seem worth the effort to me This is an experimental prototype for developers - if you don't understand the instructions, it's probably not for you
  20. The Windows installer can be - source/tools/dist/build.sh creates it (plus the Unix tarballs etc), using NSIS via Wine. (NSIS can be run natively on Linux instead, but it needs to be compiled in 32-bit mode so it's a pain on 64-bit Gentoo and I stuck with Wine instead.)
  21. That's a critical fact and makes a big difference . (Also, zip compresses each file individually, while the installer compresses everything as a single chunk so it can exploit redundancy between files too.) I think the main ones are lots of Ogg Vorbis files (which are hard to compress further), and lots of DDS textures (which are compressed but are easy to compress further).
  22. Oops, fixed now. (Also I slightly cleaned up and committed some earlier changes that I'd used to get the game launching, though I haven't tested the current code on Android yet.) You need to use the game engine to create the zip, since it has to convert all the textures/models/animations/etc into a different format before zipping them up. Build a standard non-Android copy of the game, then run like "binaries/system/pyrogenesis -archivebuild=binaries/data/mods/public -archivebuild-output=temp/public.zip" and it should print lots of output and will take a while (maybe ten minutes or more). Then (optionally) extract that ~700MB public.zip into a new directory and zip it all up again so that it's properly compressed to ~300MB. Then copy to /sdcard/0ad/data/mods/public/public.zip and the game should see it. (If you want to change a few data files after that, you don't need to regenerate public.zip - just copy the individual files straight into mods/public/ and they'll override the zipped version.) Also, copy binaries/data/config/default.cfg into /sdcard/0ad/appdata/config/. Hopefully that's about enough, but I might be forgetting things. The game's log messages are visible through "adb logcat" so that should indicate when things are going wrong.
  23. Day 15 Worked on various minor fixes to make the pathfinding less broken, and updated the JPS A* to work with the real technical requirements (correct diagonal movement, non-point goal areas, etc), so it's nearly possible to test performance in a proper gameplay environment. Some more thoughts on JPS: Intuitively (i.e. very informally and maybe wrongly), JPS works because of two observations: * Shortest paths will wrap tightly around the corners of obstructions. (Imagine the path is a piece of string from the source to the destination, winding around various obstructions, then pull the string tight. It will get pulled until it's going in straight lines between the corners of the obstructions. If it's not already tight around the corners, it's not a shortest path.) * In a grid (only allowing horizontal/vertical/diagonal steps), when there are multiple equal-length paths between the same two points, you have to make an arbitrary choice between them, and you can always prefer the one that moves diagonally as early as possible. Therefore, if the pathfinding algorithm is extending a path in a horizontal/vertical direction, it can continue in a straight line until it reaches a corner to wrap around. If there is no corner, there's no point turning diagonally or 90 degrees from the current direction, because it would always be possible (and preferable) to have turned diagonally on an earlier step. (That continuance in a straight line is the "jump" in "JPS", and is what makes JPS a worthwhile optimisation.) If the algorithm is extending a path in a diagonal direction, it can continue in that direction; or it can turn 45 degrees and go horizontally/vertically (since that might still be a most-preferred shortest path); or it can wrap around a corner and turn 90 degrees. The definition of "corner" depends on how you define connectivity between grid cells. The original JPS paper says that any horizontally/vertically/diagonally adjacent passable cells are connected. Here's some diagrams of the shortest paths (in blue) from the red blob to every other cell, where black cells are impassable: In the second diagram, note that the paths can squeeze through the diagonal gap between the two impassable areas. That's a bit nasty because unit movement is not tile-based: units move along the path in arbitrary-length steps, and they might end up standing precisely on the impassable tiles' corners or (due to non-infinitely-precise maths) actually stand inside an impassable tile, which is bad. But we don't want to forbid diagonal movement entirely, because it allows much higher quality paths than purely horizontal/vertical movement. To fix that, we can declare that diagonal moves are only allowed between two passable cells (i, j) and (i+1, j+1) if the other two adjacent cells (i+1, j) and (i, j+1) are also passable. This means the diagonals do not connect any two cells unless they are already connected by horizontal/vertical steps (which incidentally simplifies other tasks like reachability testing). Now the shortest paths are like: This means the paths always stay at least half a tile away from the obstructions, so we won't suffer from numerical precision problems as before. Interestingly, the path around the corner in the very first diagram has two turns (from horizontal to diagonal, then to vertical), whereas in the new approach it only has one turn (from horizontal to vertical), so the new version might result in fewer processed A* nodes and work a bit faster. The changes to the original JPS algorithm are straightforward (unless I'm misunderstanding it and introducing bugs) - horizontal/vertical jump points occur one cell later, and have 2 forced neighbours instead of 1, while diagonals have no forced neighbours at all, so it just needs small tweaks to the code.
×
×
  • Create New...