Yves
WFG Retired-
Posts
1.135 -
Joined
-
Last visited
-
Days Won
25
Everything posted by Yves
-
Technical Triggers discussion
Yves replied to sanderd17's topic in Game Development & Technical Discussion
I've also added this little demo mission for demonstrating triggers in a multiplayer scenario and giving some ideas how they can be used. I've played it with leper yesterday, it's actually quite fun already (could use some fine-tuning though). -
[RESOLVED] Unable to build cause of spidermonkey [faulty RAM module]
Yves replied to Clovisnox's topic in Help & Feedback
Could you try deleting the whole mozjs24 folder in libraries/source/spidermonkey in addition to running clean-workspaces.sh again please? -
Build environment and deployment on the Mac
Yves replied to Yves's topic in Game Development & Technical Discussion
How's the whole build process now? Do you still manually change iconv.h? -
If you mean objects in general, there's the move-icon (2nd on the top left corner). Just click on it, then select an object and hit "Delete" on the keyboard.
-
Again, nice work! I like that map a lot
-
Technical Triggers discussion
Yves replied to sanderd17's topic in Game Development & Technical Discussion
The terms are a bit blurry here. What is a mod and what are triggers? A mod is just a directory or a zip file in binaries/data/mods that can contain anything. A mod is a very general solution for implementing custom functionality, which is good in many cases but also a problem in other situations. I'll elaborate more on that below. Triggers are basically like any other simulation component and could therefore also be part of a mod with a similar or completely different implementation. What makes them special and what we are talking about in this case is: Triggers suggest how the component system can be used to implement scripted missions by providing a suitable pattern. Triggers provide often used functionality for scripted missions like range events, timer events, predefined actions etc. Triggers simplify mission scripting for map designers In contrast to the very general concept of a mod, triggers provide additional ways of integrating custom content. In the proposed solution that's the "TriggerScripts" definition in the map JSON that defines which trigger scripts are loaded as part of the map.Our task (and my task when reviewing the patch) is to analyse if the proposed solution meets these requirements well enough and if it can be extended in the future to meet additional requirements. The most important criteria is if the suggested pattern is flexible enough. A suggested pattern is successful if it gets used in most cases and doesn't have to be replaced by another pattern. IMO this solution is very flexible and meets the requirements in this case. As far as I can tell, this patch already offers some often used functionality and the attached tutorial proof-of-concept mission shows that quite a lot can be done already. We should keep an eye on commonly used functionality that could be added to the default trigger component, but I'm quite sure that extending this implementation works well for the future. IMO the requirement is met. I think the solution can be extended in different way to simplify mission scripting for map designers (like Spahbod described for example). It already simplifies it a lot by fulfilling requirement nbr 1. However, I think we need to agree on how triggers will be presented in atlas and make sure this patch can be extended accordingly in the future before it can be committed. IMO we're on the right way but this requirement is not completely met yet. As wraitii says, we could always implement functionality with mods, which is a very general approach. General approaches have some limitations for specific cases. Flexible missions (check definition above) are hard to implement with mods for example. You could add trigger scripts to all maps, but then it quickly gets difficult if you have more than one mod and if you want to use maps from other mods with the triggers of your flexible mission. Another approach would be figuring out on your own how you can add all the functionality to the game in a general way and use it with all maps. This would probably work somehow but it would at least make it a lot more difficult for mission designers and it wouldn't be done often. I've discussed flexible missions with Sander on IRC. The requirements checking is a problem. If we want the full flexibility we'd have to load the whole map on the gamesetup screen to check for requirements. Sander suggested listing flexible missions and the associated trigger scripts in the map JSON data. This would mean the flexible mission needs to be known at map creation time, which kind of defeats the purpose. Maybe a reasonable tradeoff would be predefining some "mission script definitions" in the map JSON data. Like specifying that the map has a "InvadingArmySpawn" trigger point (or maybe "FarAwayFromPlayerSpawnPoint") or that each player starts with a CC. Then we could have trigger scripts requiring certain mission script definitions. This is just one aspect and there are some other open questions about how trigger content is provided. Random maps are another example. IMO this requirement is not yet met.I'll think about triggers a bit more this afternoon and probably add some more comments. Generally I like the approach very much and it seems to be a solid solution once the open questions are resolved. -
The plan was to apply the fixes for OS X to the same version we used for Alpha 16. Because the fixes do not require simulation behaviour changes, the OS X release will be compatible with the Alpha 16 versions on Windows and Linux. That means the OS X package release has no influence on the decision if we want a 16.1 release.
-
Technical Triggers discussion
Yves replied to sanderd17's topic in Game Development & Technical Discussion
The first thing I thought about was how triggers are assigned to maps and how tightly/loosely they should be tied to maps. Victory conditions could be implemented with triggers for example. There are well known victory conditions such as wonder, king of the hill, regicide, protecting the wonder etc. When I thought more about it, I figured maps should be more loosely tied to mission scripts (scripts containing triggers). I've made up some terms to describe what I mean... Term: Generic missions Victory conditions are basically just specific cases of small missions. For example, your first task is to collect enough resources, the second is to build a wonder and the third is to protect it long enough. So instead of calling them victory conditions, we could also call it "generic missions" and include special scripted behaviour that does not lead to victory (like a mode that gives you resources for each temple you build). Generic is referring to the map in this case and would mean that triggers only refer to things that can be done on any map or nearly any map. Again, the wonder victory condition would work for almost any game and could be implemented as generic mission (it won't work if you only have one hero on a map for example). Generic missions could be an easy way to provide customized gameplay for a large quantity of maps. Of course we could still separate the missions in the GUI into "generic missions" and "victory conditions" even if they are handled the same way in the background. Term: Flexible missions There are many other possibilities of generic missions, but they are very limited at the same time. They would be much more powerful if it was possible to define some requirements for the map without tying them to a specific map. I'll call this concept "flexible missions". Flexible missions contain a requirement definition that can be validated on the gamesetup screen to show available maps for the mission script or available mission scripts for a map. Such requirements could be: Each player has at least one building of type X at the beginningThere's a trigger point with the name "InvadingArmy1Spawn" on the map (extend trigger points with a name?)There are at least 5 entities of the type "relic" on the mapThere's a trigger point with the name "KingOfTheHillLocation"Instead of listing requirements it would probably be better to pass map data and provide a function that checks that for requirements, but that's an implementation detail. Also generic missions most likely aren't needed as a separate implementations if flexible missions are implemented. Term Scenario missions Scenario missions would be the type of mission that only makes sense with a specific map and isn't worth to be implemented as flexible mission. I'd like to avoid getting stuck because of too many ideas and things that are "nice to have". At the same time I think it's especially important to clearly define the scope of triggers. If we want features later that could have been implemented with triggers but need a completely new approach to avoid breaking existing missions, that's bad. Such generic or flexible missions would be cool in my opinion because they offer a lot of gameplay variety with little effort (little effort for adding new missions once the system is in place). -
Build environment and deployment on the Mac
Yves replied to Yves's topic in Game Development & Technical Discussion
Well, basically it's still the same problem. That "thing" must be called iconv or libiconv but not iconv here and libiconv there. EDIT: Or it could also be a mismatch with const/non const... but I think the compiler would list availaible candiates with different argument types then. -
I agree that this is a bug, but a bugfix release is not as simple as it sounds. Fixing this changes the simulation behaviour, which means multiplayer games between patched and unpatched versions aren't possible because they would go out of sync. This means we need separate multiplayer lobbies for the 16.0 and 16.1 release. All Linux distributions who have already made Alpha 16 packages need to adjust them. In addition I don't think it's a very serious bug. It can be abused in some cases, but is not completely overpowered. You could also agree not to (ab)use this bug with your opponent.
-
We had similar discussions after most releases. In many cases there were even bugs that made the game unplayable for some players. IMO it still doesn't make sense to release an Alpha bugfix release. As Sander said, there was plenty of time for testing before the release.
-
I think they still contain too many placeholders for being announced as a new civilization, so we sneaked them in.
-
Build environment and deployment on the Mac
Yves replied to Yves's topic in Game Development & Technical Discussion
But it worked for you after deleting .already-built, right? -
There is an error: ../../../source/lib/external_libraries/icu.h:31:30: fatal error: unicode/smpdtfmt.h: Aucun fichier ou dossier de ce type #include <unicode/smpdtfmt.h>Install libicu-dev (It's also in the prereq list of the build instructions).
-
It's not enabled in our engine currently, but I think this should be enough to enable it:
-
I'm not a fan of asm.js yet, but you should not draw conclusions too early. A quote from this article: A quote from this article: You might want to test with ESR31 again. I haven't tested ASM.JS yet and I don't know if/how much they improved this in the meantime.
-
Impressive, how you are combining these concepts such as the triple store, the query language and the HTN approach for planning actions based on the data and goals. It seems to be as generic as it can be and seems to be a good approach to make the AI more flexible, more configurable and easier to understand. I hope it works out as planned. Do you have a working version somewhere where these concepts could be tested in 0 A.D. directly? Even if it has just basic functionality as shown in the video, it would be interesting so experiment with that and figure out how it works. Using a git repository for your work would probably be the best way for sharing it and it's also very helpful for managing your own versioning and keeping track of changes in the development version of 0 A.D..
-
Finally! I've found the problem. The autobuild is committed and the translations should now also work on Windows.
-
@Lion You can delete the line that stats with "Locale = " from user.cfg or change the value to something else.
-
It currently looks like a bug in the VS2008 linker. When incremental linking is enabled, Link.exe crashes quite often, but I don't know if this is related. There's KB948127, but it's part of SP1 and is already installed on my system. Anyway, I think there are two similar but different issues with the crashes in 0 A.D.. The first is a crash that can happen at different places if the debug runtime is used (/MDd) and NDEBUG is specified. It always crashes in STL functions (usually constructors) but happens with many different callstacks. It looks very similar to the other issue and might be related, but I'll focus on the other one because we normally don't need /MDd plus NDEBUG. This issue happened when I removed all libraries as described in the previous post, so I didn't quite notice that the other issue was already gone. The second issue is in the Dictionary constructor with the callstack posted above. If we don't call that constructor (don't use tinygettext), the game also builds and runs properly in release mode with VS2008. This means the issue is isolated to a single place in our code. I've written a simple example-program that basically does the same as the problematic code. It has a dictionary class which is part of a static library and the main executable calls new/delete on that class (code here). In the game this crashes in the constructor when the STL map gets initialized, in the example program it works fine. Comparing the instruction that fails, I see this: Game: _Nodeptr _Buynode() { // allocate a head/nil node _Nodeptr _Wherenode = this->_Alnod.allocate(1);00205AA0 push 44h 00205AA2 call CMessageVisionRangeChanged::ToJSVal+143h (1C47E3h) 00205AA7 add esp,4 int _Linkcnt = 0;Example program: _Nodeptr _Buynode() { // allocate a head/nil node _Nodeptr _Wherenode = this->_Alnod.allocate(1);013B21D0 push 44h 013B21D2 call operator new (13B22E0h) 013B21D7 add esp,4 int _Linkcnt = 0;Callstack: > pyrogenesis.exe!std::_Tree<std::_Tmap_traits<unsigned int,StaticShape,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,StaticShape> >,0> >::_Buynode() Line 1384 C++ pyrogenesis.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > >,0> >::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > >,0> >(const std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > & _Parg=less, const std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > > & _Al={...}) Line 510 + 0xf bytes C++ pyrogenesis.exe!tinygettext::Dictionary1::Dictionary1() Line 24 + 0x15 bytes C++ pyrogenesis.exe!L10n::L10n() Line 42 + 0x2c bytes C++ pyrogenesis.exe!Init(const CmdLineArgs & args={...}, int flags=0) Line 869 + 0x2a bytes C++ pyrogenesis.exe!RunGameOrAtlas(int argc=1, const char * * argv=0x09600ff8) Line 470 C++ pyrogenesis.exe!main(int argc=1, char * * argv=0x09600ff8) Line 515 + 0xd bytes C++ pyrogenesis.exe!wmain(int argc=1, wchar_t * * argv=0x08ff2f78) Line 380 + 0xa bytes C++ pyrogenesis.exe!__tmainCRTStartup() Line 583 + 0x17 bytes C pyrogenesis.exe!CallStartupWithinTryBlock() Line 397 C++ kernel32.dll!754b338a() [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] ntdll.dll!77a29f72() ntdll.dll!77a29f45() Apparently instead of calling new, it calls another random function. Now the question is, at which stage this problem happens exactly. This assembler output is from visual studio directly (while debugging). I assume this code is part of the CRT, so in which binary would it actually be? I'd like to figure out if the binary on the disk already looks that way or if something breaks during dynamic loading.
-
I've removed tinygettext, iconv and ICU and replaced the localization functions that used them with dummy-functions. The crash still happens in release mode, but now on different places again with completely different callstacks (but always in STL). I've also replaced the singleton implementation of L10n because I suspected it could cause some rarely tested constelations that could be bugged in VS2008. That also didn't help. I guess I have to revert the patch piece by piece and implement more or less working intermediate steps to figure out which part causes these issues. Debugging in VS only produces garbage as far as I've seen so far.
-
I've figured out that the crash only happens if NDEBUG is defined. This causes the different behaviour in debug and release mode, but it doesn't help me much to figure out where the problem is exactly. Using application verifier I get this callstack which seems to make more sense: msvcp90.dll!69767290() [Frames below may be incorrect and/or missing, no symbols loaded for msvcp90.dll] > pyrogenesis.exe!tinygettext::Dictionary::Dictionary(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & charset_="UTF-8") Line 29 + 0x60 bytes C++ pyrogenesis.exe!L10n::L10n() Line 47 + 0x6f bytes C++ pyrogenesis.exe!L10n::Instance() Line 41 + 0x24 bytes C++ pyrogenesis.exe!CGUI::Xeromyces_ReadObject(XMBElement Element={...}, CXeromyces * pFile=0x0043e5a0, IGUIObject * pParent=0x25450f60, const std::vector<std::pair<CStr8,CStr8>,std::allocator<std::pair<CStr8,CStr8> > > & NameSubst=[0](), boost::unordered::unordered_set<Path,boost::hash<Path>,std::equal_to<Path>,std::allocator<Path> > & Paths={...}) Line 1317 + 0x20 bytes C++ pyrogenesis.exe!CGUI::Xeromyces_ReadObject(XMBElement Element={...}, CXeromyces * pFile=0x0043e5a0, IGUIObject * pParent=0x24bccf60, const std::vector<std::pair<CStr8,CStr8>,std::allocator<std::pair<CStr8,CStr8> > > & NameSubst=[0](), boost::unordered::unordered_set<Path,boost::hash<Path>,std::equal_to<Path>,std::allocator<Path> > & Paths={...}) Line 1227 + 0x1e bytes C++ pyrogenesis.exe!CGUI::Xeromyces_ReadObject(XMBElement Element={...}, CXeromyces * pFile=0x0043e5a0, IGUIObject * pParent=0x2338ef60, const std::vector<std::pair<CStr8,CStr8>,std::allocator<std::pair<CStr8,CStr8> > > & NameSubst=[0](), boost::unordered::unordered_set<Path,boost::hash<Path>,std::equal_to<Path>,std::allocator<Path> > & Paths={...}) Line 1227 + 0x1e bytes C++ pyrogenesis.exe!CGUI::Xeromyces_ReadRootObjects(XMBElement Element={...}, CXeromyces * pFile=0x1025222b, boost::unordered::unordered_set<Path,boost::hash<Path>,std::equal_to<Path>,std::allocator<Path> > & Paths={...}) Line 996 + 0x18 bytes C++ pyrogenesis.exe!CGUI::LoadXmlFile(const Path & Filename={...}, boost::unordered::unordered_set<Path,boost::hash<Path>,std::equal_to<Path>,std::allocator<Path> > & Paths={...}) Line 945 C++ pyrogenesis.exe!CGUIManager::LoadPage(CGUIManager::SGUIPage & page={...}) Line 227 C++ pyrogenesis.exe!CGUIManager::PushPage(const CStrW & pageName={...}, boost::shared_ptr<ScriptInterface::StructuredClone> initData={...}) Line 86 C++ pyrogenesis.exe!CGUIManager::SwitchPage(const CStrW & pageName={...}, ScriptInterface * srcScriptInterface=0x0043e808, CScriptVal initData={...}) Line 78 C++ pyrogenesis.exe!InitPs(bool setup_gui=true, const CStrW & gui_page={...}, ScriptInterface * srcScriptInterface=0x00000000, CScriptVal initData={...}) Line 525 C++ pyrogenesis.exe!InitGraphics(const CmdLineArgs & args={...}, int flags=0) Line 1031 + 0x65 bytes C++ pyrogenesis.exe!RunGameOrAtlas(int argc=1, const char * * argv=0x09454ff8) Line 470 + 0xb bytes C++ pyrogenesis.exe!main(int argc=1, char * * argv=0x09454ff8) Line 515 + 0xd bytes C++ pyrogenesis.exe!wmain(int argc=1, wchar_t * * argv=0x08ed6f98) Line 380 + 0xa bytes C++ pyrogenesis.exe!__tmainCRTStartup() Line 583 + 0x17 bytes C pyrogenesis.exe!CallStartupWithinTryBlock() Line 397 C++ kernel32.dll!7558338a() ntdll.dll!77109f72() ntdll.dll!77109f45()Someties I got even a bit closer to the crash. It happens during the initialization of an std::map object.
-
That's completely weird. It's caused by tinygettext and is related to STL types. We knew about the problem before that different runtime libraries from Microsoft use different STL implementations and this was the reason why we moved tinygettext to a static library which is built as part of the project. Building it as part of the project instead of adding a binary to the repository should ensure that tinygettext uses the same CRT (runtime) version as the engine. Somehow the STL types used in tinygettext still cause problems and I don't know why. I've reduced the problem to a very simle test-case. This code causes the crash if used from the engine. It only causes the crash if the constructor is part of the cpp file. I assume otherwise the class is compiled in the engine static library completely. Header: class Dictionary1{public: Dictionary1(); typedef std::map<std::string, std::vector<std::string> > Entries; Entries entries;};CPP file: Dictionary1::Dictionary1(){};Any ideas?
-
Some output from WinDbg: 0:000> .ecxreax=00000000 ebx=0032deac ecx=26206e23 edx=62ee2134 esi=1117e070 edi=62f083f7eip=62f08406 esp=0032dd10 ebp=0032dd48 iopl=0 nv up ei pl nz na pe nccs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210206msvcp90!std::operator<<<char,std::char_traits<char>,std::allocator<char> >+0xf:62f08406 8b4814 mov ecx,dword ptr [eax+14h] ds:002b:00000014=????????*** ERROR: Symbol file could not be found. Defaulted to export symbols for pyrogenesis.exe - 0:000> kc *** Stack trace for last set context - .thread/.cxr resets itmsvcp90!std::operator<<<char,std::char_traits<char>,std::allocator<char> >WARNING: Stack unwind information not available. Following frames may be wrong.pyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::Client::discopyrogenesis!glooxwrapper::StanzaExtension::extensionTypepyrogenesis!glooxwrapper::StanzaExtension::extensionTypepyrogenesispyrogenesispyrogenesis!glooxwrapper::Client::discopyrogenesis!std::_Init_locks::operator=pyrogenesis!glooxwrapper::Client::discokernel32!BaseThreadInitThunkntdll!__RtlUserThreadStartntdll!_RtlUserThreadStartSeems to be related to gloox somehow.
-
Update svn and try again please. Some DLL files were missing.