You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Phase 1 depends on POLYVISION_SOLO_NO_OPPONENT_MODE=1 so a one-tribe SCORE-mode map continues across END_TURN actions through the wrapper's Turn-10 horizon. TribesGymEnv.__init__() asks the Java bridge to enable that behavior with PythonEnv.setSoloNoOpponentMode(...), but catches every exception from that call and silently continues.
If the Java/Py4J bridge is stale, incompatible, or otherwise fails while setting the mode, Python can return an apparently usable environment whose turn-termination semantics no longer match the Phase 1 contract.
Why This Matters
The solo-continuation flag is not an optional optimization. In PythonEnv.stepByIndex(), it changes whether END_TURN suppresses ordinary single-tribe SCORE-mode game-over and explicitly advances the tick, restores an incomplete result, initializes the next turn, and recomputes actions. Silently failing to configure that behavior can therefore invalidate training, evaluation, or human-benchmark execution at the game-transition layer.
The repository recently made TribesGymWrapper construction fail closed when the real environment interface cannot be established (#7 / commit 5641344575b6d486df388cba82e788cdb20c556d). The lower-level bridge should provide the same guarantee for this experiment-defining mode instead of retaining a compatibility fallback that can change semantics.
Evidence
pol_env/Tribes/py/gym_env.py defaults POLYVISION_SOLO_NO_OPPONENT_MODE to enabled and calls self._env.setSoloNoOpponentMode(...) inside a broad try/except Exception: pass.
pol_env/Tribes/src/core/game/PythonEnv.java implements setSoloNoOpponentMode(boolean) and exposes getSoloNoOpponentMode().
PythonEnv.stepByIndex() computes soloContinuation = soloNoOpponentMode && singleTribe && selectedEndTurn; when true it calls gs.advance(selected, false), increments the tick, clears game-over, restores the active tribe to INCOMPLETE, initializes the new turn, and recomputes actions.
README.md, docs/human-benchmark.md, and the canonical evaluator all treat solo/no-opponent mode as part of the current Phase 1 execution contract.
tools/evaluate_phase1.py explicitly sets POLYVISION_SOLO_NO_OPPONENT_MODE=1 before constructing the environment, so official evidence generation relies on this bridge configuration succeeding.
The maintained core contract tests cover wrapper bootstrap failure semantics but do not currently protect failure or round-trip verification of the Java solo-mode configuration.
Treat requested solo/no-opponent configuration as part of the executable environment contract. When Python requests the mode, the bridge must either configure and verify the requested value or fail environment construction with the underlying cause preserved. Do not silently continue with unknown/default Java semantics.
Definition of Done
TribesGymEnv no longer silently ignores failure to call setSoloNoOpponentMode() when the mode is requested.
Environment construction verifies the Java-side value through getSoloNoOpponentMode() (or an equivalently authoritative contract check) and fails if it does not match the requested Python configuration.
A bridge/version mismatch or setter/getter failure raises a clear exception that preserves useful underlying diagnostic context.
A regression test covers at least one failed setter/getter or mismatched round-trip case.
A live contract test confirms that enabled solo mode permits the expected single-tribe END_TURN continuation semantics without changing the current successful Phase 1 behavior.
The regression is included in the maintained core CI gate.
Constraints / Non-Goals
This issue does not redesign solo gameplay, add opponents, change the Turn-10 curriculum, or introduce automatic bridge-version negotiation. It only makes the currently required Phase 1 mode explicit and fail-closed. If an intentionally supported legacy Java bridge without this API is ever needed, that should be a separate explicitly selected compatibility mode rather than an automatic silent fallback.
Validation
Run the cheap core CI with a mocked bridge that throws or reports the wrong solo-mode value and verify construction fails. Then run a live single-tribe environment path with solo mode enabled and verify an END_TURN reaches the next tick/turn rather than terminating immediately.
Audit Priority: P2
Audit Type: FIX
Problem / Opportunity
Phase 1 depends on
POLYVISION_SOLO_NO_OPPONENT_MODE=1so a one-tribe SCORE-mode map continues acrossEND_TURNactions through the wrapper's Turn-10 horizon.TribesGymEnv.__init__()asks the Java bridge to enable that behavior withPythonEnv.setSoloNoOpponentMode(...), but catches every exception from that call and silently continues.If the Java/Py4J bridge is stale, incompatible, or otherwise fails while setting the mode, Python can return an apparently usable environment whose turn-termination semantics no longer match the Phase 1 contract.
Why This Matters
The solo-continuation flag is not an optional optimization. In
PythonEnv.stepByIndex(), it changes whetherEND_TURNsuppresses ordinary single-tribe SCORE-mode game-over and explicitly advances the tick, restores an incomplete result, initializes the next turn, and recomputes actions. Silently failing to configure that behavior can therefore invalidate training, evaluation, or human-benchmark execution at the game-transition layer.The repository recently made
TribesGymWrapperconstruction fail closed when the real environment interface cannot be established (#7 / commit5641344575b6d486df388cba82e788cdb20c556d). The lower-level bridge should provide the same guarantee for this experiment-defining mode instead of retaining a compatibility fallback that can change semantics.Evidence
pol_env/Tribes/py/gym_env.pydefaultsPOLYVISION_SOLO_NO_OPPONENT_MODEto enabled and callsself._env.setSoloNoOpponentMode(...)inside a broadtry/except Exception: pass.pol_env/Tribes/src/core/game/PythonEnv.javaimplementssetSoloNoOpponentMode(boolean)and exposesgetSoloNoOpponentMode().PythonEnv.stepByIndex()computessoloContinuation = soloNoOpponentMode && singleTribe && selectedEndTurn; when true it callsgs.advance(selected, false), increments the tick, clears game-over, restores the active tribe toINCOMPLETE, initializes the new turn, and recomputes actions.README.md,docs/human-benchmark.md, and the canonical evaluator all treat solo/no-opponent mode as part of the current Phase 1 execution contract.tools/evaluate_phase1.pyexplicitly setsPOLYVISION_SOLO_NO_OPPONENT_MODE=1before constructing the environment, so official evidence generation relies on this bridge configuration succeeding.Proposed Outcome
Treat requested solo/no-opponent configuration as part of the executable environment contract. When Python requests the mode, the bridge must either configure and verify the requested value or fail environment construction with the underlying cause preserved. Do not silently continue with unknown/default Java semantics.
Definition of Done
TribesGymEnvno longer silently ignores failure to callsetSoloNoOpponentMode()when the mode is requested.getSoloNoOpponentMode()(or an equivalently authoritative contract check) and fails if it does not match the requested Python configuration.END_TURNcontinuation semantics without changing the current successful Phase 1 behavior.Constraints / Non-Goals
This issue does not redesign solo gameplay, add opponents, change the Turn-10 curriculum, or introduce automatic bridge-version negotiation. It only makes the currently required Phase 1 mode explicit and fail-closed. If an intentionally supported legacy Java bridge without this API is ever needed, that should be a separate explicitly selected compatibility mode rather than an automatic silent fallback.
Validation
Run the cheap core CI with a mocked bridge that throws or reports the wrong solo-mode value and verify construction fails. Then run a live single-tribe environment path with solo mode enabled and verify an
END_TURNreaches the next tick/turn rather than terminating immediately.