A picture instead of million words
Extending events
So how to handle reset() or freeze()/unfreeze() of worldview. ISensors method reset() is not enough as we may need to just fade out and moreover reset() really means “synchronize with logic” so the name is wrong. It should be something like “doLogicEnded” or “worldViewUnfrozen” so the sensor module can listen for it / do something as this event arises. Thus we should provide such methods in general and let people listen for them soing whatever they need when such event is received.
Thus we should implement more events in core in general. And we need probably new layer for this virtual events / virtual commands.
MODULES - LAST PROPOSITION
Memory modules will be only simple - almost just a sensors. They will work in sync with doLogic() methods. “Memory” will registers various listeners to WorldView and store events between doLogic() calls.
A) doLogic is called
B) doLogic is running and querying memory modules which are frosen
C) doLogic ends
D) memory modules are cleared and new events that came during A/B/C are commited to the modules
E) goto A
We're assuming we have only SyncThreaded bot (no ASync threaded bot)
interface ISensoryModule {
public void reset(); // this will wipe the sensory readings in the module
}
ISensoryModule.reset();
//will be called in D before the WorldView is "resumed" (not to wipe fresh informations).
This leads to the problem that we need registerModule() method that will allow user to subscribe his/hers module.
BOT types
1) event-driven bot … has listener on END message that starts the doLogic, doLogic will be at first implemented by us and will check whether last doLogic didn't took too much time
2) concurrent bot … has second thread must have LockableWorldView!
Body module
Questions: ergonomy of names
1) you don't know what you need and want to seek body.simple.locomotion.move()
2) or you know what you're doing and have just loc.move() or body.move()
interface SimpleModyle
interface AdvancedModule extends SimpleModule (only if viable)
IMap, IPathPlanner, IPathExecutor
Executor —- calls —→ PathPlanner —- uses information from —→ Map
interface IMap {
// already done I think as a specific type of event
}
interface IPathPlannner {
public void getPathTo(ILocation location);
} // can be GameBots / Floyd-Warshall / A * / etc.
// two types of IPathPlanner ... sync (A *, etc...) / async (GB)
interface IPathExecutor {
public void goTo(ILocation location);
}
- stricly event based - produce events for everything (path started, path can't be obtained, path broken, location reached, etc. … doesn't matter whether it uses sync path planner or async path planner
IPathExecutor register itself to WorldView watching for events that needs to be handled (e.g. steering / dodging ~ hear noises…)
IPathExecutor defines new events (is source of events): path broken / location reached
We should have also path executor decorators like “InterruptiblePathExecutor” that will watch for user-sent commands RunTo and TurnTo and stops itself upon such action.
RayTracingManager
Implements: ISensoryModule
Upon calling reset() clears sensory readings of all rays it has
Methods:
interface IRayTracingModule {
IRay addRay(way, distance)
// returns IRay object that represents the new ray sensor
removeRay(IRay ray)
clearRays()
}
interface IRay {
boolean get() // whether the ray bounces
AutoTraseMessage getMessage() // details of the sensor reading
}
Interface IPickupableObject
has own id
has type
extends InfoObject ? why?
IInventory object in the base … creates new type of event: pickup (lost?)
GesturesManager
has 2 binary connection to GameBots. Through this connection it can trigger animations for the bot.
generate event BMLAct finished.
it can also sends regular GameBots commands through normal GB connection (such as MESSAGE or TURNTO) - this commands are necessary for more complex BMLActs that would feature synchronization of speech with gesture or with gesture and some simple movement.
works in two modes - good and evil.
In evil mode, when some BMLAct is executed, the module will take completely over the Bot control (logic will freeze, or no commands could be run by logic). Logic is resumed after the act is finished.
In good mode, when some BMLAct is executed, the logic is not stopped. It can ask the module if the gesture is still running. The event BMLAct finished is called when the act is finished. When some other command is run by the logic when we are executing the Act, we will interrupt the BML act and perhaps we can generate some ActInterrupted event…
Modules descriptions
You can add/change the description of proposed modules. The image source can be found in the SVN repository in \branches\devel\docs\documentation\architecture\media\ - UT2004Agent.svg.
Questions:
Where and how will be implemented good old Pogamut methods?
prePrepareAgent()
postPrepareAgent()
shutdownAgent()
The protocol HandShake is a bit messy in our core (as Jakub noted), what we will do with it?
How we should store packages in the agents - body, sensors, memory, worldview - what should be the hierarchy?
Ondra
they should be as independent as possible.
General remark. There are too many methods/commands for a beginner, I would do almost everywhere sort of SimpleMemory, SimpleCommands, SimpleNavigation etc. and create a few (lets say 2-3) bots using strictly those interfaces. So the beginner won't be overwhelmed and disgusted by a hundred of methods he should know about.
Commands module
- in fact two modules - one for beginners, one for experts
ICommands
all possible commands even those from simple commands, so user does not have to remember, where are which commands
usage: agent.commands.command(parameters);
There will be body.act(ICommand) - all commands can be executed this way (as defined in XMLs)
NEW: Commands are being implemented. See them in repository. package cz.cuni…bot.commands
SimpleLomotion
MoveTo(Location) - simple RUNTO command, input anything that implements ILocated or is location.
Stop() <SC> - stops the bot immediately
TurnHorizontal(amount) - roll is not used for bots.
TurnVertical(amount)
TurnTo(Location) - target can be again object or location…
Jump() <SC>
Run() - disables walking
Walk() - enables walking
AdvancedLocomotion
StrafeTo(Target,Focus) - now Focus can be both object or location - Should we create two strafe methods, or allow all of this in one?
MoveContinuously(Speed) - issue CMOVE command
Rotate(Axis, Amount) - which axis and how much. Can be divided into two methods RotateHorizontaly and Verticaly
DoubleJump() <SC>
Crouch() <SC> X Uncrouch() <SC>
setSpeed(double) - sets speed.
AdvancedShooting
ShootPrimary(Target) - Target - anything ILocated. Split into ShootPrimary, ShootSecondary ?
ShootSecondary(Target)
Shoot(Target, Mode, Time) - how long we should be shooting
ShootCharged(Target,Mode) - for charging weapons… Probably is the same as above command with special settings
ChangeWeapon(Weapon)<SC> - Weapon in inventory with correct inventoryId
ChangeWeaponToBest()<SC> - issues UnrealScript command.
Jakub Gemrot
Shoot(Target,mode) - I don't want to write true/false every shoot command
ChangeWeaponToBest() is sort of magical - it's hard to explain to beginner in details but I don't see other option here
Radim Vansa
Would be possible to use ChangeWeapon(something.suggestWeapon()) method? Is there in UnrealScript only command to change to best weapon, or is there any way to ask before changing to it? Another question is what should be the “something” - some module that should collect info about weapons with simple default implementation suggesting regardless of the attributes passed?
Action
ThrowWeapon() - throws current weapon out. Should be here or in other?
Respawn()
startAdrenalineCombo(String)
Ondrej Burkert
? UseItem() - runs animation on item? decrease its quantity by one, destroys item?
? UseItem(amount) - decreases its quantity by amount - to be able to eat apples, etc…
? AddInventory(Inventory) - adds inventory to the bot.
MichalBida
- shouldn't this be in inventory?
Configure commands
Init(attributes) - sends init command. Should be either here or in no cathegory - not sure.
we already have configure command that is easy to use (nobody would ever to write true/false combination there as you usually do not know what all those fields means!) instead you may use body.act(new Configure().setWalk(true).setAutoTrace(false)); notice the sequence of setters
Communication
SendMessage(Global, Text)<SC> - global or team message.
SendMessageTo(UnrealId, Text)<SC> - private message
SendTextBubble(Text)
SetDialog(UnrealId,DialogId,Text,Option0-Option9) - sets dialog by bot for a player who has the bot selected
Ondrej Burkert
How about a new module ICommunication? which will give some sort of message handling capabilities? Thought I have no exact idea about what it should do exactly.
SendMessageBubble(Text) - shows some bubble over the agent with a message - I am not sure, whether this is possible, I just remember that Michal said something about such a feature.
Michal Bida
Yes, this is possible by simply issuing MESSAGE command with correct attributes -
GB API.
IRayTracing
getIsRayTracing() - on/off
getAllRays()
getLastRayResult(rayId) - for one ray
getAllRayResults(rayId, Time) - for one ray, since what time
getLastRaysResults() - for all rays
getAllRaysResults(Time) - for all rays
getHasIssuedTrace/FastTraceCommand()
getLastTraceResult(Id)
getLastFastTraceResult(Id)
getAllTraceResult(Time)
getAllFastTraceResult(Time)
INavigation
PathPlanner will include the IMap object inside as it will be the source of information about the map and MovementManager will be responsible for steering. dodging etc … (the interfaces are already in the devel branche) . The moveAlongPath method will use default implementations of these interfaces underneath.
part of implementation is a path manager and path finder (interfaces to give a way to define own pathfinding, by default
GB)
this module will be included in IMap, or Imap should be included in INavigation. How we will do this?
Methods
safeRunToLocation()
GetPath(Target) - target can be location or Ilocated.
RunAlongPath(Id of path)
RunAlongList(list of Ilocated objects) - will request paths and do everything automaticaly
ReachCheck(Target) - anything Ilocated.
GetPath()
RunAlongListOfILocated(List)
nearestWeapon(type)
nearestXY()
visibleSomething() - this should be also in memory. right?
or seeSomething(type) - this should be also in memory. right?
IMap
IListeners
ISensors
IMemory
isThreatenedByProjectile() - projectile that can possibly hit us
hasPickedUp()
hasNewInventory() - should this be here?
hasHit() - Hit message
hasCollided() - to wall, WAL message
hasFallen() - FAL message
hasHearedNoise - HRN or HRP message
hasReceivedMessage - MESSAGE
hasZoneChanged() - zone change message
getThreateningProjectile() - or Projectiles ? can be more of them
getLastPickup()
getLastNewInventory() - should this be here?
getLastHit()
getLastWallCollision()
getLastFallLocation()
getLastMessage()
getLastNoise()
getLastZoneChange()
getLastKill()
getLastMyKill()
getLastDeath()
getAllHits(Time)
getAllThreateningProjectiles(Time)
getAllPickups(Time)
getAllNewInventory(Time) - should this be here?
getAllWallCollisions(Time) - since that time return all wall collisions we heared
getAllFalls(Time) - since that time return all falls we heared
getAllMessages(Time) - since that time return all messages we heared
getAllNoises(Time) - since that time return all noises we heared
getAllZoneChanges(Time)
getAllKills(Time)
getAllMyKills(Time)
getAllDeaths(Time)
Jakub Gemrot
IGestures
Should provide a way to make the bot animate our custom defined gestures
Will have to pause the bot - stop moving, turning - this can be added as a precondition or it can be forced. Then we will start to run the animation, when it is ready we will let the logic know. Should we pause the logic when the animation is executing? Should the user handle animating more in logic? Or should we handle it here?
ExecuteAnimation(Animation)
ExecuteAnimation(List<Animation>)
IsAnimating()
StopAnimation()
IInventory
I would give a possibility to add listeners for Weapon, Ammo, other events:
Methods
UseItem(Id)
getInventory(Id)
getAllInventoryCategory(Category)
getAllInventory()
getAllWeapons()
getCurrentWeapon() - implemented in memory Self.
hasLoadedWeapon()
getLoadedWeapons()
getBestLoadedWeapon()
getWeaponProperties(Weapon)
getWeaponFiringModes(Weapon)
getWeaponFiringModeRange(Weapon,Mode), Splash(), Damage() … all info we will know!
setAutoRearming(boolean value) - when set to true, bot will rearm automatically when out of ammo
switchToBestWeapon() - basic command, implemented in commands if uses UnrealScript reasoning
switchToBestWeapon(Player enemy) - some basic reasoning about distance and available weapons - just to create some example of reasoning
Ondra
switchToBestWeapon(Player target) should be implemented in one of example bots… people don't dig in implementation of something, but they study a lot example bots. (just an impression from the week of science)
destroyItem(id) - destroy item in inventory, can be named useItem or something
User defined modules
Episodic Memory / Emotions / etc.
We can clearly see on the picture where can our kind user put them:).
Remote Control
What buttons should remote control have (picture is just a shot)
Has move forward a bit - ~ 200 ut units
Move backward a bit - ~ 150 ut units (value should be different from move forward - that way we can set the bot better to desired position)
Strafe Left, Right ~ 100 ut units
Turn Left/Right ~ 4000 ut units (rotation units)
Stop and Jump button
Run button - can work in two ways - sends CMOVE command when pushed and STOP when released or (i think better) sends just CMOVE and to Stop the bot, STOP button has to be pressed.
PauseLogic button
SendCommand field and button - for directly sending text command to
GB!
What about recording sequence of commands from remote control for a bot and then store them somewhere?
Add TOGGLE buttons, that would be kept down and issue some command (MOVE,TURN,ETC.)
RemoteControl would force pause logic for a certain time - let's say 1 second to let the bot finish the command sent by a remote control. It is more confusing without it. User tries to move a bot but he seems not responding - in fact he is just overriding every user's command before it can even be executed.