They are all good for this, except PHP Its possible but wouldn't recommend it for an object oriented language. VB is to my knowledge not really cross platform, although for a BOT its not really that important to support cross platform applications.
C++ often requires knwledge on the lower level to make it truly cross platform. So I really like to develop on a cross platform framework language such as .NET. I have not tried out wxWidgets .NET yet but when devleoping on OpenGL libraries for .NET you can publish cross-platform with minimal code adjustments.
So I would recommend VB.NET or C# with wxWidgets.NET and OpenGL. You can also expose bot interfaces as COM so you can support the VB6 / Microsoft managed C++ users without having to write extra code.
I think there are also wrappers for unmanaged C++ to call .NET libraries.
Ofcourse if you develop in C++ it also works the other way around, but again, C++ does not have one standardized development framework, but there are many frameworks. Which can make cross platform implementations very complicated.
Like Edwin I have been working on a VR environment for some years now, my focus has been primarily on the architecture, how broad can it be used for example.
Here are some examples of my BOT interface to the platform 3D environment. Note its a more High Level Language and much more managed than that off ActiveWorlds SDK. Furthermore the bot can not only interact with text, or 3D objects. It has access to EVERYTHING. furthermore a bot can be configured to run via Internet Connection or Plugged in to the Universe Server directly (for performance). With allowing a BOT to have complete control you can do more with it than just 3D VR Worlds. IE. 2D or Pseudo 3D games are also possible.
We have been privately developing this platform, but I am looking on opening up Platform3D bot development this year.
In this example it sends a welcome greeting to the user and adds skybox (i.e. the world will be controlled by a bot).
It also interacts with user status changes, in just a couple lines of code (most code is generate through intellisens). It currently supports:
In the Near Future these languages will also be supported
PLATFORM3D BOT SDK Examples
In VB.NET
Code: Select all
Public Class GreeterBotExample
Inherits BaseBot
Public Sub New(ByVal configuration As ClientEngineInstanceConfiguration)
MyBase.New(configuration)
AddHandler MyBase.OnEnterWorldResponse, New EnterWorldResponseDelegate(AddressOf Me.GreeterBotExample_OnEnterWorldResponse)
AddHandler MyBase.OnServerConnectResponse, New ServerConnectResponseDelegate(AddressOf Me.GreeterBotExample_OnServerConnectResponse)
AddHandler MyBase.OnLifeformChatStatusChanged, New OnLifeformChatStatusChangedDelegate(AddressOf Me.GreeterBotExample_OnLifeformChatStatusChanged)
MyBase.Start
End Sub
Private Sub GreeterBotExample_OnEnterWorldResponse(ByVal sender As EnterWorldResponseMessage, ByVal e As EventArgs)
If ((Not sender.LifeformId.Value Is MyBase.BotId) AndAlso (sender.EnumResponseCode = WorldResponseCode.WORLD_LIFEFORM_ENTERED_SUCCESSFULLY)) Then
MyBase.BeginSendChatMesage((sender.LifeformName.Value & " enters..."), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0)
MyBase.BeginSendSkyBox(sender.LifeformId.Value, "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_lf.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_rt.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_up.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_dn.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_fr.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_bk.jpg")
End If
End Sub
Private Sub GreeterBotExample_OnLifeformChatStatusChanged(ByVal sender As ChatStatusResponseMessage, ByVal e As EventArgs)
Select Case sender.ChatStatus
Case LifeformChatStatus.CHAT_STATUS_AVAILABLE
MyBase.BeginSendChatMesage(("Welcome back " & MyBase.Cache.GetLifeform(sender.LifeFormId.Value).Name & "."), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0)
Exit Select
Case LifeformChatStatus.CHAT_STATUS_BE_RIGHT_BACK
MyBase.BeginSendChatMesage((MyBase.Cache.GetLifeform(sender.LifeFormId.Value).Name & " will be right back."), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0)
Exit Select
Case LifeformChatStatus.CHAT_STATUS_DO_NOT_DISTURB
MyBase.BeginSendChatMesage((MyBase.Cache.GetLifeform(sender.LifeFormId.Value).Name & " does not want to be more disturbed than this."), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0)
Exit Select
Case LifeformChatStatus.CHAT_STATUS_AFK
MyBase.BeginSendChatMesage((MyBase.Cache.GetLifeform(sender.LifeFormId.Value).Name & " is away from keyboard."), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0)
Exit Select
End Select
End Sub
Private Sub GreeterBotExample_OnServerConnectResponse(ByVal sender As ServerConnectResponseMessage, ByVal e As EventArgs)
MyBase.BeginAuthenticate("############", "######")
End Sub
End Class
In DELPHI
Code: Select all
public GreeterBotExample = class(BaseBot)
// Methods
constructor GreeterBotExample.Create(configuration: ClientEngineInstanceConfiguration);
begin
inherited OnEnterWorldResponse += EnterWorldResponseDelegate.Create(self,GreeterBotExample_OnEnterWorldResponse);
;
inherited OnServerConnectResponse += ServerConnectResponseDelegate.Create(self,GreeterBotExample_OnServerConnectResponse);
;
inherited OnLifeformChatStatusChanged += OnLifeformChatStatusChangedDelegate.Create(self,GreeterBotExample_OnLifeformChatStatusChanged);
;
inherited Start
end;
procedure GreeterBotExample.GreeterBotExample_OnEnterWorldResponse(sender: EnterWorldResponseMessage; e: EventArgs);
begin
if ((sender.LifeformId.Value <> inherited BotId) and ((sender.EnumResponseCode as WorldResponseCode) = WorldResponseCode.WORLD_LIFEFORM_ENTERED_SUCCESSFULLY)) then
begin
inherited BeginSendChatMesage(string.Concat(sender.LifeformName.Value, ' enters...'), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
inherited BeginSendSkyBox(sender.LifeformId.Value, 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_lf.jpg', 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_rt.jpg', 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_up.jpg', 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_dn.jpg', 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_fr.jpg', 'http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_bk.jpg')
end
end;
procedure GreeterBotExample.GreeterBotExample_OnLifeformChatStatusChanged(sender: ChatStatusResponseMessage; e: EventArgs);
begin
case sender.ChatStatus of
LifeformChatStatus.CHAT_STATUS_AVAILABLE:
begin
inherited BeginSendChatMesage(string.Concat('Welcome back ', inherited Cache.GetLifeform(sender.LifeFormId.Value).Name, '.'), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
end;
LifeformChatStatus.CHAT_STATUS_BE_RIGHT_BACK:
begin
inherited BeginSendChatMesage(string.Concat(inherited Cache.GetLifeform(sender.LifeFormId.Value).Name, ' will be right back.'), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
end;
LifeformChatStatus.CHAT_STATUS_DO_NOT_DISTURB:
begin
inherited BeginSendChatMesage(string.Concat(inherited Cache.GetLifeform(sender.LifeFormId.Value).Name, ' does not want to be more disturbed than this.'), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
end;
LifeformChatStatus.CHAT_STATUS_AFK:
begin
inherited BeginSendChatMesage(string.Concat(inherited Cache.GetLifeform(sender.LifeFormId.Value).Name, ' is away from keyboard.'), ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
end;
end
end;
procedure GreeterBotExample.GreeterBotExample_OnServerConnectResponse(sender: ServerConnectResponseMessage; e: EventArgs);
begin
inherited BeginAuthenticate('######', '#############')
end;
end;
In MS C++
Code: Select all
public __gc class GreeterBotExample : public BaseBot
{
// Methods
public: GreeterBotExample(ClientEngineInstanceConfiguration __gc* configuration) : base(configuration)
{
base->OnEnterWorldResponse += new EnterWorldResponseDelegate __gc*(this.GreeterBotExample_OnEnterWorldResponse);
base->OnServerConnectResponse += new ServerConnectResponseDelegate __gc*(this.GreeterBotExample_OnServerConnectResponse);
base->OnLifeformChatStatusChanged += new OnLifeformChatStatusChangedDelegate __gc*(this.GreeterBotExample_OnLifeformChatStatusChanged);
base->Start();
}
private: void __gc* GreeterBotExample_OnEnterWorldResponse(EnterWorldResponseMessage __gc* sender, EventArgs __gc* e)
{
if ((sender->LifeformId->Value != base->BotId) && (*static_cast<__box WorldResponseCode*>(sender->EnumResponseCode) == WorldResponseCode::WORLD_LIFEFORM_ENTERED_SUCCESSFULLY))
{
base->BeginSendChatMesage(String::Concat(sender->LifeformName->Value, S" enters..."), ChatMessageType::CHAT_MESSAGE_PUBLIC, 0);
base->BeginSendSkyBox(sender->LifeformId->Value, S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_lf.jpg", S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_rt.jpg", S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_up.jpg", S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_dn.jpg", S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_fr.jpg", S"http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_bk.jpg");
}
}
private: void __gc* GreeterBotExample_OnLifeformChatStatusChanged(ChatStatusResponseMessage __gc* sender, EventArgs __gc* e)
{
switch (sender->ChatStatus)
{
case LifeformChatStatus::CHAT_STATUS_AVAILABLE:
{
base->BeginSendChatMesage(String::Concat(S"Welcome back ", base->Cache->GetLifeform(sender->LifeFormId->Value)->Name, S"."), ChatMessageType::CHAT_MESSAGE_PUBLIC, 0);
break;
}
case LifeformChatStatus::CHAT_STATUS_BE_RIGHT_BACK:
{
base->BeginSendChatMesage(String::Concat(base->Cache->GetLifeform(sender->LifeFormId->Value)->Name, S" will be right back."), ChatMessageType::CHAT_MESSAGE_PUBLIC, 0);
break;
}
case LifeformChatStatus::CHAT_STATUS_DO_NOT_DISTURB:
{
base->BeginSendChatMesage(String::Concat(base->Cache->GetLifeform(sender->LifeFormId->Value)->Name, S" does not want to be more disturbed than this."), ChatMessageType::CHAT_MESSAGE_PUBLIC, 0);
break;
}
case LifeformChatStatus::CHAT_STATUS_AFK:
{
base->BeginSendChatMesage(String::Concat(base->Cache->GetLifeform(sender->LifeFormId->Value)->Name, S" is away from keyboard."), ChatMessageType::CHAT_MESSAGE_PUBLIC, 0);
break;
}
}
}
private: void __gc* GreeterBotExample_OnServerConnectResponse(ServerConnectResponseMessage __gc* sender, EventArgs __gc* e)
{
base->BeginAuthenticate(S"#######", S"###########");
}
};
In C# (prefered language)
Code: Select all
public class GreeterBotExample : BaseBot
{
// Methods
public GreeterBotExample(ClientEngineInstanceConfiguration configuration) : base(configuration)
{
base.OnEnterWorldResponse += new ClientEngineInstance.EnterWorldResponseDelegate(this.GreeterBotExample_OnEnterWorldResponse);
base.OnServerConnectResponse += new ClientEngineInstance.ServerConnectResponseDelegate(this.GreeterBotExample_OnServerConnectResponse);
base.OnLifeformChatStatusChanged += new ClientEngineInstance.OnLifeformChatStatusChangedDelegate(this.GreeterBotExample_OnLifeformChatStatusChanged);
base.Start();
}
private void GreeterBotExample_OnEnterWorldResponse(EnterWorldResponseMessage sender, EventArgs e)
{
if ((sender.LifeformId.Value != base.BotId) && (((WorldResponseCode) sender.EnumResponseCode) == WorldResponseCode.WORLD_LIFEFORM_ENTERED_SUCCESSFULLY))
{
base.BeginSendChatMesage(sender.LifeformName.Value + " enters...", ChatMessageRequestMessage.ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
base.BeginSendSkyBox(sender.LifeformId.Value, "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_lf.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_rt.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_up.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_dn.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_fr.jpg", "http://cube33.brinkster.net/media/skybox/zolsky4/zolsky04_bk.jpg");
}
}
private void GreeterBotExample_OnLifeformChatStatusChanged(ChatStatusResponseMessage sender, EventArgs e)
{
switch (sender.ChatStatus)
{
case LifeformChatStatus.CHAT_STATUS_AVAILABLE:
base.BeginSendChatMesage("Welcome back " + base.Cache.GetLifeform(sender.LifeFormId.Value).Name + ".", ChatMessageRequestMessage.ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
case LifeformChatStatus.CHAT_STATUS_BE_RIGHT_BACK:
base.BeginSendChatMesage(base.Cache.GetLifeform(sender.LifeFormId.Value).Name + " will be right back.", ChatMessageRequestMessage.ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
case LifeformChatStatus.CHAT_STATUS_DO_NOT_DISTURB:
base.BeginSendChatMesage(base.Cache.GetLifeform(sender.LifeFormId.Value).Name + " does not want to be more disturbed than this.", ChatMessageRequestMessage.ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
case LifeformChatStatus.CHAT_STATUS_AFK:
base.BeginSendChatMesage(base.Cache.GetLifeform(sender.LifeFormId.Value).Name + " is away from keyboard.", ChatMessageRequestMessage.ChatMessageType.CHAT_MESSAGE_PUBLIC, 0);
break;
}
}
private void GreeterBotExample_OnServerConnectResponse(ServerConnectResponseMessage sender, EventArgs e)
{
base.BeginAuthenticate("##########", "###########");
}
}
Bot Extensions Diagram overview
