Ticket #4127: init_simulation_seed_v1.patch

File init_simulation_seed_v1.patch, 6.9 KB (added by elexis, 8 years ago)

The tests added only test that boosts returns random numbers, not that the seed is actually initialized in the simulation. Not sure how to do that, there should be Simulation2 tests that include mapreader tests.

  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

    function launchGame()  
    12801280        let player = g_PlayerAssignments[guid];
    12811281        if (player.player > 0)  // not observer or GAIA
    12821282            g_GameAttributes.settings.PlayerData[player.player - 1].Name = player.name;
    12831283    }
    12841284
    1285     // This seed is only used for map-generation
    1286     if (g_GameAttributes.mapType == "random")
    1287         g_GameAttributes.settings.Seed = Math.floor(Math.random() * 65536);
    1288 
    1289     g_GameAttributes.settings.AISeed = Math.floor(Math.random() * 65536);
     1285    // Seed used for both map generation and simulation
     1286    g_GameAttributes.settings.Seed = Math.floor(Math.random() * Math.pow(2, 32));
     1287    g_GameAttributes.settings.AISeed = Math.floor(Math.random() * Math.pow(2, 32));
    12901288
    12911289    // Used for identifying rated game reports for the lobby
    12921290    g_GameAttributes.matchID = Engine.GetMatchID();
    12931291
    12941292    if (g_IsNetworked)
  • source/simulation2/Simulation2.cpp

    void CSimulation2::SetMapSettings(const  
    759759}
    760760
    761761void CSimulation2::SetMapSettings(JS::HandleValue settings)
    762762{
    763763    m->m_MapSettings = settings;
     764
     765    u32 seed = 0;
     766    if (!m->m_ComponentManager.GetScriptInterface().GetProperty(m->m_MapSettings, "Seed", seed))
     767        LOGWARNING("CSimulation2::SetInitAttributes: No seed value specified - using %d", seed);
     768
     769    m->m_ComponentManager.SetRNGSeed(seed);
    764770}
    765771
    766772std::string CSimulation2::GetMapSettingsString()
    767773{
    768774    return m->m_ComponentManager.GetScriptInterface().StringifyJSON(&m->m_MapSettings);
  • source/simulation2/Simulation2.h

    public:  
    106106    void GetInitAttributes(JS::MutableHandleValue ret);
    107107
    108108    /**
    109109     * Set the initial map settings (as a UTF-8-encoded JSON string),
    110110     * which will be used to set up the simulation state.
     111     * Called from atlas.
    111112     */
    112113    void SetMapSettings(const std::string& settings);
    113114
    114115    /**
    115116     * Set the initial map settings, which will be used
    116117     * to set up the simulation state.
     118     * Called from MapReader (for all map-types).
    117119     */
    118120    void SetMapSettings(JS::HandleValue settings);
    119121
    120122    /**
    121123     * Get the current map settings as a UTF-8 JSON string.
    public:  
    266268     */
    267269    std::string GetAIData();
    268270
    269271private:
    270272    CSimulation2Impl* m;
     273
    271274};
    272275
    273276#endif // INCLUDED_SIMULATION2
  • source/simulation2/system/ComponentManager.cpp

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
    CComponentManager::CComponentManager(CSi  
    5959    m_SimContext(context), m_CurrentlyHotloading(false)
    6060{
    6161    context.SetComponentManager(this);
    6262
    6363    m_ScriptInterface.SetCallbackData(static_cast<void*> (this));
    64 
    65     // TODO: ought to seed the RNG (in a network-synchronised way) before we use it
    6664    m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG);
    6765    m_ScriptInterface.LoadGlobalScripts();
    6866
    6967    // For component script tests, the test system sets up its own scripted implementation of
    7068    // these functions, so we skip registering them here in those cases
    void CComponentManager::ResetState()  
    538536    // Reset IDs
    539537    m_NextEntityId = SYSTEM_ENTITY + 1;
    540538    m_NextLocalEntityId = FIRST_LOCAL_ENTITY;
    541539}
    542540
     541void CComponentManager::SetRNGSeed(u32 seed)
     542{
     543    m_RNG.seed(seed);
     544}
     545
    543546void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
    544547        const char* name, const std::string& schema)
    545548{
    546549    ComponentType c(CT_Native, iid, alloc, dealloc, name, schema, std::move(DefPersistentRooted<JS::Value>()));
    547550    m_ComponentTypesById.insert(std::make_pair(cid, std::move(c)));
  • source/simulation2/system/ComponentManager.h

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
    public:  
    293293     * Resets the dynamic simulation state (deletes all entities, resets entity ID counters;
    294294     * doesn't unload/reload component scripts).
    295295     */
    296296    void ResetState();
    297297
     298    /**
     299     * Initializes the random number generator with a seed determined by the host.
     300     */
     301    void SetRNGSeed(u32 seed);
     302
    298303    // Various state serialization functions:
    299304    bool ComputeStateHash(std::string& outHash, bool quick);
    300305    bool DumpDebugState(std::ostream& stream, bool includeDebugInfo);
    301306    // FlushDestroyedComponents must be called before SerializeState (since the destruction queue
    302307    // won't get serialized)
  • source/simulation2/tests/test_ComponentManager.h

    public:  
    9494        TS_ASSERT_EQUALS(man.AllocateNewEntity(), (u32)2);
    9595        TS_ASSERT_EQUALS(man.AllocateNewEntity(3), (u32)3);
    9696        TS_ASSERT_EQUALS(man.AllocateNewLocalEntity(), (u32)FIRST_LOCAL_ENTITY);
    9797    }
    9898
     99    void test_rng()
     100    {
     101        // Ensure we get the same random number with the same seed
     102        // and two different numbers with two different seeds
     103        for (int test=0; test<2; ++test)
     104        {
     105            CSimContext context;
     106            CComponentManager man(context, g_ScriptRuntime);
     107            man.SetRNGSeed(1);
     108            double first;
     109            if (!man.m_ScriptInterface.MathRandom(first))
     110                TS_FAIL("Couldn't get random number!");
     111
     112            CSimContext context2;
     113            CComponentManager man2(context2, g_ScriptRuntime);
     114            double second;
     115            man2.SetRNGSeed(test == 0 ? 1 : 2);
     116            if (!man2.m_ScriptInterface.MathRandom(second))
     117                TS_FAIL("Couldn't get random number!");
     118
     119            if (test == 0)
     120                TS_ASSERT_EQUALS(first, second);
     121
     122            if (test == 1)
     123                TS_ASSERT_DIFFERS(first, second);
     124        }
     125    }
     126
    99127    void test_AddComponent_errors()
    100128    {
    101129        CSimContext context;
    102130        CComponentManager man(context, g_ScriptRuntime);
    103131        man.LoadComponentTypes();