avaraline / avara Goto Github PK
View Code? Open in Web Editor NEWPort of the original 1996 game from Ambrosia Software.
License: MIT License
Port of the original 1996 game from Ambrosia Software.
License: MIT License
To do away with resource fork reading completely, we need to export all the sounds from HSND to a modern format (currently possible with hsnd2wav + other tools, which will be incorporated into the level converter).
But also Avara needs to be able to load and play those sounds into its own sound system. It should be possible to bypass the Huffman decoding step, add any necessary decoding of the chosen format (OGG or other) and give sample data directly to the sound mixer.
Windows: Prefer an installer, msi? VC++ redistributables?
Mac: Prefer an app bundle -- I think this is mostly taken care of, we just need an organizational signing ID ($$?)
Linux: Prefer some kind of installer package, probably deb?
We're targeting Inkscape specific SVG for a couple reasons:
That last part should open up interesting ideas for level editing, such as
Some of this can be done completely outside of Avara code, some of it will require making Avara rendering available from a python library or something similar integrated with Inkscape.
uncaught exception of type utf8::not_enough_room: Not enough space
To reproduce: start a game, enter chat mode, type "option-L" or similar
Immediate crash, of everyone connected
This could have to do with the inputBuffer field of CPlayerManager:
Avara/src/game/CPlayerManager.cpp
Lines 258 to 263 in a8352bb
In any case, whether or not we fix the underlying issue, the exception could be caught and discarded
The default team colors have been resurrected from 1996 and they look pretty bad. We should keep the general base colors so that references to team colors in level sets are still valid, but we can do better than #FF0000.
Additionally, we should either add these team colors to be configurable in user preferences for local view only, or consider adding a color shift that makes the team colors distant enough for discernment among color-impaired users.
Because we can't change colors of levels, or references to team colors, adding a text name of the team color to the roster interface is recommended (for example, if red is selected, the word "Red" is shown somewhere in the interface alongside it). This can allow a user to get the basic idea of what adjusted shade translates to which baseline team color, and makes team membership clearer overall.
With the move away from resource forks, we need a method of storing a level set's drawings (svg), sounds (wav or other format), metadata (jsons of resource data) and shapes (avarabsps).
Avara originally worked by overlaying the level set resource files with its own to allow the level sets to override specific resources in the base game and change shapes or other configuration.
Our solution must also be able to dynamically search for a given resource ID from an Avara base level data file and then from the currently loaded set file.
Reported by @ryansommers
Restart of machine and update of Xbox controller driver fixed issue once.
Probably mouse capture/SDL related. Could possibly be SDL controller support related. Not a ton of info to go off of on this one quite yet.
The original game had functionality where you could put the Avara application in the background and be excluded from consideration for inclusion in a new starting game, for example if you happened to step away for a few minutes. Other games could still start without considering you as a participant.
Rather than mess with cross-platform application focus, we can provide the same functionality with some kind of ready toggle button that appears on the roster after a level becomes loaded. This would only be on the local player's roster row, the other players would simply show the ready status, rather than a toggle button. It is probably possible to re-use the same flag that Avara used for being backgrounded to signal this over the network.
This indicator could also be used to absorb the purpose of the status line and provide more information with less text. I'm thinking of an icon for each player's status and ready selection, with perhaps the current status text descriptions and more info in a tooltip, for example ping or optional profile settings (location, realname)
I ghetto-rigged a system together that requires you to hover over the chat window in order to type in it, so that I don't steal focus from the other text boxes in the UI. We should figure out a way to make the chat box the default for handling text input unless you actually click into the other text fields (like server, tracker, etc.)
Hey, original author of level "Chut" here (aka DudyPowder). I've found my old map on-line, how do I play it in here?
I made a bunch of maps back in the day but haven't found them all...
Some memorable stuff:
There is code in place that is meant to change the ball's kMarkerColor
according to the team color of the player carrying it, but it does not seem to work.
I'm having trouble getting friends to download this port and the SDL and SDL_net dependencies are causing some friction.
Would it be possible to create binaries that include these two dependencies and maybe make a nice avara.github.io page with download lniks for brain-dead 2 minute frictionless installs? You guys have done great work with this port and I'd love to see it get some adoption from the non tech elite...
Lines 33 to 40 in ce6c5aa
This has caused issues with distance calculations before in FDistanceEstimate, and writing some dumb C++ that matches the old less accurate computations in assembly seemed to help with that. Hoping that doing the same here will have positive effects on several other issues we are experiencing.
The workaround for this is to do an export SDL_AUDIODRIVER=alsa
before launching Avara
The zoom in / zoom out keys are only respected as far as culling. Check to see how zoom is implemented and adjust AvaraGL view matrix.
Right now, updates happen every 64ms (frameTime). None of the frame actions take into account how long the frame actually is, since it was hard-coded in Avara. So trying to run the game at shorter frame times (for better network performance, higher FPS, etc) works, but results in speeding up the whole game - movement is much faster since the same movements happen in shorter times, gravity feels stronger, etc.
This is a pretty big task, since it touches a LOT of the game code, and has implications for LT handling. It's not as critical now that the game loop has been refactored so events and rendering can happen more than once per frame. We may even decide 64ms is still the "right" frameTime for now, but decoupling it would open up some options.
The UFOs don't behave correctly, some in the single player never come down to player level, some are WAY too fast (the "AI" code also determines the UFO's speed). Their aim is OK, and I think turn rate looks OK, but their movement has problems.
Possibly fixed by closing #95
Thanks for porting this game! I have kicked myself ever since I sold our last Mac, so found your port the best Christmas present ever. ;)
There are some issues, though.
Compiled Avara in VirtualBox 6.0.0 VM running Ubuntu 18.10, on a Windows 10 OS.
Using SDL2-2.0.9 and SDL2_net-2.0.1. Wonder if all the below problems could be solved if I compiled for Windows natively, but don't know how to do that. Any instructions posted along that line to the github repository would be welcomed.
Once the level is loaded, you can run around and fire weapons with no problem or lag, but the mouse control is very difficult. I can't get audio to work, either, but I'll worry about that later.
The easiest way to see this happening is to load Treble from AA Tre and look at the columnar blocks in the center. The decorations on top show z-fighting artifacts on Windows.
This may be distance related since they look fine when you're playing/up close, but I've also seen it on the corner blocks in Symbiosis at pretty close range.
It may also be platform related, but you can definitely see this in both Windows and Linux.
After following the instructions, make
won't run:
culle@LAPTOP-H0OVMH6B MSYS ~/Avara
# make
mkdir -p build/src/audio/
clang++ -Isrc/audio -Isrc/base -Isrc/bsp -Isrc/compat -Isrc/game -Isrc/gui -Isrc/level -Isrc/net -Isrc/util -Isrc/util/huffman -Ivendor/glad -Ivendor/nanovg -Ivendor/nanogui -Ivendor/pugixml -Ivendor -Ivendor -Ivendor/gtest/include -MMD -MP -g -Wno-multichar -DNANOGUI_GLAD -std=c++17 -c src/audio/CBasicSound.cpp -o build/src/audio/CBasicSound.cpp.o
make: clang++: No such file or directory
make: *** [Makefile:116: build/src/audio/CBasicSound.cpp.o] Error 127
culle@LAPTOP-H0OVMH6B MSYS ~/Avara
# make winapp
mkdir -p build/src/audio/
clang++ -Isrc/audio -Isrc/base -Isrc/bsp -Isrc/compat -Isrc/game -Isrc/gui -Isrc/level -Isrc/net -Isrc/util -Isrc/util/huffman -Ivendor/glad -Ivendor/nanovg -Ivendor/nanogui -Ivendor/pugixml -Ivendor -Ivendor -Ivendor/gtest/include -MMD -MP -g -Wno-multichar -DNANOGUI_GLAD -std=c++17 -c src/audio/CBasicSound.cpp -o build/src/audio/CBasicSound.cpp.o
make: clang++: No such file or directory
make: *** [Makefile:116: build/src/audio/CBasicSound.cpp.o] Error 127
Neither clang or clang++ are available under those names, although the makefile is looking for them:
CC = clang
CXX = clang++
I've run the suggested pacman/dependency command. Running Windows 10 v1909. Let me know if I can provide anything else! Also interested in map design, I did some neat stuff with the original a long time ago and it'd be neat to see if someone out there still had any of it.
FDistanceEstimate in the old version was some 68000 ASM that did an approximation of a square root based on chapter 8 of Graphics Gems (per a comment Juri left). Our implementation just does a square root, which gives subtly different (and more accurate) numbers. This is having unintended consequences on gameplay behavior, because this function is used in a lot of places to measure different things. For example
So instead of doing the square root, we should try to implement the old algorithm in C++
Transition from using PICT resources to SVG drawings, establishing a feature parity between the two formats. This will enable level diffs, better editing, easier hashing, and brings us one step closer to not requiring the original resource forks.
When outside of a game, you can type "¬" with impunity, unless it is the last character in the line when you press Enter.
The source of the issue seems to lie in std::string CPlayerManagerImpl::GetChatLine()
, which examines the line buffer to grab the most recent line of chat by finding the last "¬" character (the assumption being that it marked the end of the line prior to the one we want). A substring is returned containing everything following that point. Unfortunately, when the last character in the buffer just happens to be a "¬", an invalid index is submitted to substr
, hence the crash.
Checking for this specific condition is unfortunately not sufficient, because another issue would remain: typing "asdf ¬ qwerty" followed by Enter would result in "qwerty" being returned, rather than the full string.
Here's the backtrace:
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x00007fff702ab33a libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff70367e60 libsystem_pthread.dylib`pthread_kill + 430
frame #2: 0x00007fff70232808 libsystem_c.dylib`abort + 120
frame #3: 0x00007fff6d492458 libc++abi.dylib`abort_message + 231
frame #4: 0x00007fff6d4838a7 libc++abi.dylib`demangling_terminate_handler() + 238
frame #5: 0x00007fff6efbe5b1 libobjc.A.dylib`_objc_terminate() + 104
frame #6: 0x00007fff6d491887 libc++abi.dylib`std::__terminate(void (*)()) + 8
frame #7: 0x00007fff6d4941a2 libc++abi.dylib`__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 27
frame #8: 0x00007fff6d494169 libc++abi.dylib`__cxa_throw + 113
frame #9: 0x00007fff6d4750c8 libc++.1.dylib`std::__1::__throw_out_of_range(char const*) + 56
frame #10: 0x00007fff6d466b0e libc++.1.dylib`std::__1::__basic_string_common<true>::__throw_out_of_range() const + 16
frame #11: 0x00007fff6d466daf libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long, std::__1::allocator<char> const&) + 195
frame #12: 0x00000001000f34f7 Avara`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::substr(this="¬", __pos=3, __n=18446744073709551615) const at string:3280:12
frame #13: 0x00000001000f33b5 Avara`CPlayerManagerImpl::GetChatLine(this=0x0000000102905000) at CPlayerManager.cpp:745:20
frame #14: 0x00000001000f2d47 Avara`CPlayerManagerImpl::RosterMessageText(this=0x0000000102905000, len=0, c=" \"normal\": [\n -0.11374074921797517,\n -0.9801174944686045,\n 0.1624628061341268\n ],\n \"tris\": [\n?-\x89\x01\x01") at CPlayerManager.cpp:710:90
frame #15: 0x00000001000d862c Avara`CNetManager::ReceiveRosterMessage(this=0x00000001022a5ee0, slotId=0, len=1, c="\r \"normal\": [\n -0.11374074921797517,\n -0.9801174944686045,\n 0.1624628061341268\n ],\n \"tris\": [\n?-\x89\x01\x01") at CNetManager.cpp:349:20
frame #16: 0x0000000100026c34 Avara`CProtoControl::DelayedPacketHandler(this=0x000000010228d1c0, thePacket=0x0000000101892c80) at CProtoControl.cpp:89:21
frame #17: 0x0000000100026879 Avara`DelayedProtoHandler(thePacket=0x0000000101892c80, userData="\x98K.") at CProtoControl.cpp:37:24
frame #18: 0x000000010000ee24 Avara`CCommManager::ProcessQueue(this=0x0000000100f9d990) at CCommManager.cpp:363:33
frame #19: 0x00000001000d7a41 Avara`CNetManager::ProcessQueue(this=0x00000001022a5ee0) at CNetManager.cpp:188:21
frame #20: 0x00000001000c3360 Avara`CAvaraGame::GameTick(this=0x0000000102911c00) at CAvaraGame.cpp:815:13
frame #21: 0x000000010005c3d9 Avara`CAvaraAppImpl::idle(this=0x00000001022612a0) at CAvaraApp.cpp:105:17
frame #22: 0x0000000100220678 Avara`nanogui::mainloop(refresh=16) at common.cpp:82:25
frame #23: 0x00000001002c02f7 Avara`main(argc=1, argv=0x00007ffeefbff5d8) at Avara.cpp:67:5
frame #24: 0x00007fff70163cc9 libdyld.dylib`start + 1
frame #25: 0x00007fff70163cc9 libdyld.dylib`start + 1
Before we start publishing pre-built binary releases, it would probably be good to code-sign them. Right now, the mac binaries we build are "quarantined" so you have to move them before launching or else they fail to load some resources. See https://lapcatsoftware.com/articles/app-translocation.html for more details.
Weapon slivers currently have incorrect colors included. Player slivers sometimes also have random yellow or red colors, this is either due to color replacement problems or the way that slivers gather a random color from the "exploding" shape.
Screenshot shows results from firing a grenade. Note that the player's walker colors have been included in the colors used for slivers.
Currently if you press OPT + V on a Mac in the port, two checkmarks appear--because you're both typing a checkmark and triggering the hardcoded shortcut for platforms that don't have a checkmark mapped to alt+v. This can probably be fixed pretty easily with compile time flags.
see avaraline/avara-level-converter#1 - this is a self intersecting shape
Probably not super difficult, since our data is just a rearrangement of data from common APIs
https://github.com/avaraline/Avara/blob/master/bin/rsrc_tools/bspt/reader.py#L303-L337
I made this https://github.com/assertivist/avarabsp-blender-exporter a while ago, need to see if it actually works
There are a couple issues that revolve around black and white hull colors:
Code is in place that is meant to replace the color of the scout, but it is not working.
The parts for the legs appear in CWalkerActor
, itself a subclass of CAbstractPlayer
(which is normally where special colors are applied), so I'm not sure why this ever worked in the original source. Maybe a peculiarity with Think C?
The HUD simply reads the value of the longTeamColor
property in CAbstractPlayer
, so this will need to be set another way. I'd recommend ditching the property entirely if possible and replacing it with a method that converts teamColor
to the corresponding long
value. In that case we'd want to move it to CAbstractActor
.
When a game in progress is paused and resumed, any ambient sounds that may have been playing do not pick back up.
I was lazy when porting the network code and didn't bother byte-swapping most of the numbers, since most architectures are little-endian nowadays. But it should be done at some point. This is mostly PacketInfo
and UDPPacketInfo
.
Currently the projection matrix is hard-coded to 4:3. If you stretch your window out wider than it is tall, the rendering code does nothing to adjust for this, and just stretches everything out:
It probably shouldn't try to support every extreme resolution, but it should at least try to take into account the window aspect ratio from SDL and adjust the rendering projection aspect ratio (and probably field of view to a certain extent) to prevent warping
A dynamic solution seems possible because everything's so lightweight, but a simpler alternative could be just setting up specific resolutions that you can switch between with preferences.
I know 15fps is the original fraeme rate... but how much work would be involved for a 60fps fork?
"Yon" is Avara's concept of how close you must be to be able to see/view an object. Avara had gnarly culling algorithms that would show parts of shapes as you closed in on the yon distance for that object. We will probably not pull that off easily, but a simple LOD effect can be used in place of this.
This should be a fairly simple addition to the object shader, adding another parameter for the yon value.
Of course, the favorite example of this yon effect are the missiles on top of the end structures in Net-1. It also provides an example of its effect on gameplay in the original.
We've talked about this a bit in the past but never formally created an issue for it, but being able to "record" games and play them back would not just be a fun feature, but a useful one.
It would allow us to more easily create tests for gameplay code (e.g. grenade arcs, missile tracking, regen rates, etc.) and ensure we don't break anything or change the feel of the game while working on other issues like #11.
In other circumstances, it may help us reproduce and debug crashes. We'd be able to play games normally, and in the case of a crash, replay the recording later from within gdb/lldb.
CNetManager.cpp:483 GatherPlayers()
This method gets called at the start of a network game to ensure all players are within activePlayersDistribution
. To do this there is a do/while
loop that runs the network ProcessQueue
function until all players are ready or the goAhead
flag is set by timeout (1800 ticks).
For whatever reason this often fails in practice in internet games, sometimes completely locking all clients. There should probably be a way to reconcile which players are active faster, or restart the process to attempt to get the game started faster and/or avoid an error state.
Marking this a bug because the original had it:
Avara/src/game/CPlayerManager.cpp
Lines 496 to 512 in 30ded35
This is used when a network stall happens. We've discussed other methods of resolving network stalls, like just kicking users out of the game, but i think this is still useful--other solutions will still have a timeout before they apply, specific user types will just have bad connections.
I'm thinking an easy way to do this, rather than a dialog in nanogui or something like that, is just drawing a message on the screen with nanovg, and include a specific key combination (manually checked in the events, right there at that spot, not a mapped key) that will allow users to abort whatever network wait they're experiencing. If implemented here in the same place as the original it should work the same way and allow the other connections to remain active and then start a new game.
For extra sauce points, the thing would be able to indicate in the HUD somehow which players are not sending packets. The game does send a status message to the console, but while the network is blocking that doesn't update so it is only if you wait out the lag do you see the 'problem player'.
Currently the game will not launch without being able to create an OpenGL 3.3 context. This is a pretty high bar, especially for ARM platforms, which mostly target OpenGL ES.
There are different ways to do this, one way I've read that people do it manually is just to try opening different contexts (OpenGL 3.3, then 2.x, then ES) until one works, and then adjust the shaders with text replacement and feature removal if thats necessary, to get them to compile against the target context.
AFAIK we do not use any features specific to OpenGL 3.3 that are not available in 2.x/ES, and it may be possible to adjust the shaders so that they will work against any of those contexts, but I haven't seen an easily digestible example of this yet.
I've also looked at ANGLE, which is a library Google uses to support graphics acceleration on multiple platforms. Lots of large open source projects use this, and I think it would be good to use, seeing as they have committed to delivering Metal support, which we may need for macos in the somewhat near future. I am not totally sure how much restructure of our code would be necessary to use it vs. the above approach.
The score page works locally--you can test it by playing a level single player, damaging yourself, taking note of your score, ending the game and then checking the score page.
The score page does NOT work when reporting the score from a network game. You can see how this works, right after you end a network game, if you are not the winner, BEFORE any other players exit the game, the score screen is accurate (from your local copy of the scores).
But, as soon as the game ends or a player exits the game, they send the scores packet, and it is loaded into the local scores table. Something is wrong with this code, because the numbers get all crazy.
From the Avara Level Design Manual:
// Lights (default light settings are stored here)
ambient = 0.4
light[0].i = 0.4 light[0].a = 45 light[0].b = 20
light[1].i = 0.3 light[1].a = 20 light[1].b = 200
light[2].i = 0.0 light[2].a = 45 light[2].b = 90
light[3].i = 0.0 light[3].a = 45 light[3].b = 180
There are four posible light sources in addition to ambient light. To place a lightsource, give it an intensity (the i component) between 0 and 1.0. The two angles indicate the direction that the light is coming from. The b angle is the compass reading and the a angle is the angle from the horizon. All lights are monochromatic white.
avara_frag.glsl
should be modified to handle multiple (configurable) directional light sources, and similarly allow the ambient light to be configurable.
Avara's network architecture was developed for poor modem connections. With the vast availability of broadband, we should be able to handle a few more players than 6. This may need to wait until the frame rate is able to be increased and other network issues are flushed out.
Following the instructions provided on the main GitHub page to install MSYS and build Avara on Windows 7 x64, but the make and make winapp commands produce the following output respectively:
$ make
mkdir -p build/src/audio/
clang++ -Isrc/audio -Isrc/base -Isrc/bsp -Isrc/compat -Isrc/game -Isrc/gui -Isrc/level -Isrc/net -Isrc/util -Isrc/util/huffman -Ivendor/glad -Ivendor/nanovg -Ivendor/nanogui -Ivendor -MMD -MP -g -Wno-multichar -DNANOGUI_GLAD -fPIC -std=c++1y -c src/audio/CBasicSound.cpp -o build/src/audio/CBasicSound.cpp.o
clang++: error: unsupported option '-fPIC' for target 'x86_64-w64-windows-gnu'
make: *** [Makefile:86: build/src/audio/CBasicSound.cpp.o] Error 1
$ make winapp
mkdir -p build/src/audio/
clang++ -Isrc/audio -Isrc/base -Isrc/bsp -Isrc/compat -Isrc/game -Isrc/gui -Isrc/level -Isrc/net -Isrc/util -Isrc/util/huffman -Ivendor/glad -Ivendor/nanovg -Ivendor/nanogui -Ivendor -MMD -MP -g -Wno-multichar -DNANOGUI_GLAD -fPIC -std=c++1y -c src/audio/CBasicSound.cpp -o build/src/audio/CBasicSound.cpp.o
clang++: error: unsupported option '-fPIC' for target 'x86_64-w64-windows-gnu'
make: *** [Makefile:86: build/src/audio/CBasicSound.cpp.o] Error 1
Such as
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.