mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
Add an 'Evaluate' RL endpoint, intended for dynamic game balancing
This adds a new endpoint to the RL interface for evaluating custom JavaScript. When combined with the ability to create arbitrary modifiers, this provides the required functionality for exploring quantitative game balancing. Patch By: irishninja Fixes #5981 Differential Revision: https://code.wildfiregames.com/D3479 This was SVN commit r24962.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
let playerEnt = cmpPlayerManager.GetPlayerByID('1');
|
||||
let cmpModifiersManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ModifiersManager);
|
||||
cmpModifiersManager.AddModifiers("cheat/fastactions", {
|
||||
"Cost/BuildTime": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }],
|
||||
"ResourceGatherer/BaseSpeed": [{ "affects": [["Structure"], ["Unit"]], "multiply": 1000 }],
|
||||
"Pack/Time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }],
|
||||
"Upgrade/Time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }],
|
||||
"ProductionQueue/TechCostMultiplier/time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }]
|
||||
}, playerEnt);
|
||||
@@ -78,15 +78,17 @@ def test_walk():
|
||||
|
||||
def test_attack():
|
||||
state = game.reset(config)
|
||||
units = state.units(owner=1, type='cavalry')
|
||||
unit = state.units(owner=1, type='cavalry')[0]
|
||||
target = state.units(owner=2, type='female_citizen')[0]
|
||||
initial_health = target.health()
|
||||
initial_health_target = target.health()
|
||||
initial_health_unit = unit.health()
|
||||
|
||||
state = game.step([zero_ad.actions.reveal_map()])
|
||||
|
||||
attack = zero_ad.actions.attack(units, target)
|
||||
attack = zero_ad.actions.attack([unit], target)
|
||||
state = game.step([attack])
|
||||
while state.unit(target.id()).health() >= initial_health:
|
||||
while (state.unit(target.id()).health() >= initial_health_target
|
||||
) and (state.unit(unit.id()).health() >= initial_health_unit):
|
||||
state = game.step()
|
||||
|
||||
def test_chat():
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import zero_ad
|
||||
import json
|
||||
import math
|
||||
from os import path
|
||||
|
||||
game = zero_ad.ZeroAD('http://localhost:6000')
|
||||
scriptdir = path.dirname(path.realpath(__file__))
|
||||
with open(path.join(scriptdir, '..', 'samples', 'arcadia.json'), 'r') as f:
|
||||
config = f.read()
|
||||
|
||||
with open(path.join(scriptdir, 'fastactions.js'), 'r') as f:
|
||||
fastactions = f.read()
|
||||
|
||||
def test_return_object():
|
||||
state = game.reset(config)
|
||||
result = game.evaluate('({"hello": "world"})')
|
||||
assert type(result) is dict
|
||||
assert result['hello'] == 'world'
|
||||
|
||||
def test_return_null():
|
||||
result = game.evaluate('null')
|
||||
assert result == None
|
||||
|
||||
def test_return_string():
|
||||
state = game.reset(config)
|
||||
result = game.evaluate('"cat"')
|
||||
assert result == 'cat'
|
||||
|
||||
def test_fastactions():
|
||||
state = game.reset(config)
|
||||
game.evaluate(fastactions)
|
||||
female_citizens = state.units(owner=1, type='female_citizen')
|
||||
house_tpl = 'structures/spart/house'
|
||||
house_count = len(state.units(owner=1, type=house_tpl))
|
||||
x = 680
|
||||
z = 640
|
||||
build_house = zero_ad.actions.construct(female_citizens, house_tpl, x, z, autocontinue=True)
|
||||
# Check that they start building the house
|
||||
state = game.step([build_house])
|
||||
step_count = 0
|
||||
new_house = lambda _=None: state.units(owner=1, type=house_tpl)[0]
|
||||
initial_health = new_house().health(ratio=True)
|
||||
while new_house().health(ratio=True) == initial_health:
|
||||
state = game.step()
|
||||
|
||||
assert new_house().health(ratio=True) >= 1.0
|
||||
@@ -27,3 +27,7 @@ class RLAPI():
|
||||
post_data = '\n'.join(names)
|
||||
response = self.post('templates', post_data)
|
||||
return zip(names, response.decode().split('\n'))
|
||||
|
||||
def evaluate(self, code):
|
||||
response = self.post('evaluate', code)
|
||||
return json.loads(response.decode())
|
||||
|
||||
@@ -25,6 +25,9 @@ class ZeroAD():
|
||||
self.current_state = GameState(json.loads(state_json), self)
|
||||
return self.current_state
|
||||
|
||||
def evaluate(self, code):
|
||||
return self.api.evaluate(code)
|
||||
|
||||
def get_template(self, name):
|
||||
return self.get_templates([name])[0]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user